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 2013/09/04 16:43:42 UTC

svn commit: r1520036 - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/context/servlet/ impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ impl/src/test/java/org/apache/myfaces/mc/te...

Author: lu4242
Date: Wed Sep  4 14:43:42 2013
New Revision: 1520036

URL: http://svn.apache.org/r1520036
Log:
MYFACES-3770 Implement <f:resetValues> tag and <f:ajax resetValues=true ... > 

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml   (with props)
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIOutput.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/PartialViewContextImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreLibrary.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreTestCase.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java Wed Sep  4 14:43:42 2013
@@ -672,8 +672,8 @@ public class UIInput extends UIOutput im
      */
     public void resetValue()
     {
+        super.resetValue();
         setSubmittedValue(null);
-        setValue(null);
         setLocalValueSet(false);
         setValid(true);
     }

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIOutput.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIOutput.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIOutput.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIOutput.java Wed Sep  4 14:43:42 2013
@@ -80,7 +80,7 @@ public class UIOutput extends UIComponen
      */
     public void resetValue()
     {
-        //TODO: Implement me!
+        setValue(null);
     }
 
     /**

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Wed Sep  4 14:43:42 2013
@@ -36,6 +36,9 @@ import javax.el.MethodExpression;
 import javax.el.ValueExpression;
 import javax.faces.FactoryFinder;
 import javax.faces.application.ProjectStage;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
 import javax.faces.context.FacesContext;
 import javax.faces.context.PartialViewContext;
 import javax.faces.event.AbortProcessingException;
@@ -85,6 +88,8 @@ public class UIViewRoot extends UICompon
     private static final PhaseProcessor PROCESS_VALIDATORS_PROCESSOR = new ProcessValidatorPhaseProcessor();
     private static final PhaseProcessor UPDATE_MODEL_PROCESSOR = new UpdateModelPhaseProcessor();
 
+    private static final VisitCallback RESET_VALUES_CALLBACK = new ResetValuesCallback();
+    
     /**
      * Class that is used to create the view scope map. This strategy
      * allows change the implementation of view scope map to use cdi or
@@ -106,6 +111,7 @@ public class UIViewRoot extends UICompon
         }
         VIEW_SCOPE_PROXY_MAP_CLASS = viewMapClass;
     }
+
     /**
      * The counter which will ensure a unique component id for every component instance in the tree that doesn't have an
      * id attribute set.
@@ -1335,7 +1341,9 @@ public class UIViewRoot extends UICompon
     public void resetValues(FacesContext context,
                         java.util.Collection<java.lang.String> clientIds)    
     {
-        //TODO: Implement me!
+        VisitContext visitContext = (VisitContext) VisitContext.createVisitContext(
+            context, clientIds, null);
+        this.visitTree(visitContext, RESET_VALUES_CALLBACK);
     }
 
     /**
@@ -1793,4 +1801,16 @@ public class UIViewRoot extends UICompon
             return _onPhase;
         }
     }
+    
+    private static class ResetValuesCallback implements VisitCallback
+    {
+        public VisitResult visit(VisitContext context, UIComponent target)
+        {
+            if (target instanceof EditableValueHolder)
+            {
+                ((EditableValueHolder)target).resetValue();
+            }
+            return VisitResult.ACCEPT;
+        }
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/PartialViewContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/PartialViewContextImpl.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/PartialViewContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/PartialViewContextImpl.java Wed Sep  4 14:43:42 2013
@@ -102,6 +102,7 @@ public class PartialViewContextImpl exte
     private Boolean _renderAll = null;
     private PartialResponseWriter _partialResponseWriter = null;
     private VisitContextFactory _visitContextFactory = null;
+    private Boolean _resetValues = null;
 
     public PartialViewContextImpl(FacesContext context)
     {
@@ -730,6 +731,18 @@ public class PartialViewContextImpl exte
         return _visitContextFactory;
     }
 
+    @Override
+    public boolean isResetValues()
+    {
+        if (_resetValues == null)
+        {
+            String value = _facesContext.getExternalContext().getRequestParameterMap().
+                get(RESET_VALUES_PARAM_NAME);
+            _resetValues = "true".equals(value);
+        }
+        return _resetValues;
+    }
+
     private class PhaseAwareVisitCallback implements VisitCallback
     {
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreLibrary.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreLibrary.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreLibrary.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreLibrary.java Wed Sep  4 14:43:42 2013
@@ -82,6 +82,8 @@ public final class CoreLibrary extends A
         this.addTagHandler("passThroughAttributes", PassThroughAttributesHandler.class);
 
         this.addTagHandler("phaseListener", PhaseListenerHandler.class);
+        
+        this.addTagHandler("resetValues", ResetValuesActionListenerHandler.class);
 
         this.addComponent("selectItem", UISelectItem.COMPONENT_TYPE, null, SelectItemHandler.class);
 

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java?rev=1520036&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java Wed Sep  4 14:43:42 2013
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.jsf.core;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import javax.el.ELException;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.component.ActionSource;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+import javax.faces.view.ActionSource2AttachedObjectHandler;
+import javax.faces.view.facelets.ComponentHandler;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagException;
+import javax.faces.view.facelets.TagHandler;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.view.facelets.FaceletCompositionContext;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+@JSFFaceletTag(
+            name = "f:resetValues",
+            bodyContent = "empty")
+public class ResetValuesActionListenerHandler extends TagHandler
+    implements ActionSource2AttachedObjectHandler
+{
+    /**
+     * 
+     */
+    @JSFFaceletAttribute(name = "render", className = "javax.el.ValueExpression",
+                         deferredValueType = "java.lang.Object")
+    private final TagAttribute _render;
+    
+    private final Collection<String> _clientIds;
+
+    public ResetValuesActionListenerHandler(TagConfig config)
+    {
+        super(config);
+        _render = getRequiredAttribute("render");
+        if (_render.isLiteral())
+        {
+            String value = _render.getValue();
+            if (value == null)
+            {
+                _clientIds = Collections.emptyList();
+            }
+            else
+            {
+                String[] arrValue = value.split(" ");
+                _clientIds = Arrays.asList(arrValue);
+            }
+        }
+        else
+        {
+            _clientIds = null;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.faces.view.facelets.FaceletHandler#apply(javax.faces.view.facelets.FaceletContext, javax.faces.component.UIComponent)
+     */
+    public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
+            ELException
+    {
+        //Apply only if we are creating a new component
+        if (!ComponentHandler.isNew(parent))
+        {
+            return;
+        }
+        if (parent instanceof ActionSource)
+        {
+            applyAttachedObject(ctx.getFacesContext(), parent);
+        }
+        else if (UIComponent.isCompositeComponent(parent))
+        {
+            if (getAttribute(JSFAttr.FOR_ATTR) == null)
+            {
+                throw new TagException(tag, "is nested inside a composite component"
+                        + " but does not have a for attribute.");
+            }
+            FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
+            mctx.addAttachedObjectHandler(parent, this);
+        }
+        else
+        {
+            throw new TagException(this.tag,
+                    "Parent is not composite component or of type ActionSource, type is: " + parent);
+        }
+    }
+
+    public void applyAttachedObject(FacesContext context, UIComponent parent)
+    {
+        // Retrieve the current FaceletContext from FacesContext object
+        FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(
+                FaceletContext.FACELET_CONTEXT_KEY);
+
+        ActionSource as = (ActionSource) parent;
+        ActionListener listener = null;
+        if (_render.isLiteral())
+        {
+            listener = new LiteralResetValuesActionListener(_clientIds);
+        
+        }
+        else
+        {
+            listener = new ResetValuesActionListener(_render
+                .getValueExpression(faceletContext, Object.class));
+        }
+        as.addActionListener(listener);
+    }
+
+    /**
+     * TODO: Document me!
+     */
+    @JSFFaceletAttribute
+    public String getFor()
+    {
+        TagAttribute forAttribute = getAttribute("for");
+        
+        if (forAttribute == null)
+        {
+            return null;
+        }
+        else
+        {
+            return forAttribute.getValue();
+        }
+    }
+    
+    private final static class ResetValuesActionListener implements ActionListener, Serializable
+    {
+        private static final long serialVersionUID = -9200000013153262119L;
+
+        private ValueExpression renderExpression;
+        
+        private ResetValuesActionListener()
+        {
+        }
+        
+        public ResetValuesActionListener(ValueExpression renderExpression)
+        {
+            this.renderExpression = renderExpression;
+        }
+
+        public void processAction(ActionEvent event) throws AbortProcessingException
+        {
+            FacesContext faces = FacesContext.getCurrentInstance();
+            if (faces == null)
+            {
+                return;
+            }
+            UIViewRoot root = faces.getViewRoot();
+            if (root == null)
+            {
+                return;
+            }
+            Object value = renderExpression.getValue(faces.getELContext());
+            Collection<String> clientIds = null;
+            if (value == null)
+            {
+                value = Collections.emptyList();
+            }
+            if (value instanceof Collection)
+            {
+                clientIds = (Collection) value;
+            }
+            else if (value instanceof String)
+            {
+                String[] arrValue = ((String)value).split(" ");
+                clientIds = Arrays.asList(arrValue);
+            }
+            else
+            {
+                throw new IllegalArgumentException("Type " + value.getClass()
+                        + " not supported for attribute render");
+            }
+            
+            // Calculate the final clientIds
+            UIComponent contextComponent = event.getComponent();
+            List<String> list = new ArrayList<String>();
+            for (String id : clientIds)
+            {
+                list.add(getComponentId(faces, contextComponent, id));
+            }
+            
+            // Call resetValues
+            root.resetValues(faces, list);
+        }
+    }
+    
+    private final static class LiteralResetValuesActionListener implements ActionListener, Serializable
+    {
+        private static final long serialVersionUID = -9200000013153262119L;
+
+        private Collection<String> clientIds;
+        
+        private LiteralResetValuesActionListener()
+        {
+        }
+        
+        public LiteralResetValuesActionListener(Collection<String> clientIds)
+        {
+            this.clientIds = clientIds;
+        }
+
+        public void processAction(ActionEvent event) throws AbortProcessingException
+        {
+            FacesContext faces = FacesContext.getCurrentInstance();
+            if (faces == null)
+            {
+                return;
+            }
+            UIViewRoot root = faces.getViewRoot();
+            if (root == null)
+            {
+                return;
+            }
+            
+            // Calculate the final clientIds
+            UIComponent contextComponent = event.getComponent();
+            List<String> list = new ArrayList<String>();
+            for (String id : clientIds)
+            {
+                list.add(getComponentId(faces, contextComponent, id));
+            }
+            
+            root.resetValues(faces, list);
+        }
+    }
+    
+    private static final String getComponentId(FacesContext facesContext, 
+        UIComponent contextComponent, String id)
+    {
+        UIComponent target = contextComponent.findComponent(id);
+        if (target == null)
+        {
+            target = contextComponent.findComponent(
+                facesContext.getNamingContainerSeparatorChar() + id);
+        }
+        if (target != null)
+        {
+            return target.getClientId(facesContext);
+        }
+        return id;
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ResetValuesActionListenerHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java Wed Sep  4 14:43:42 2013
@@ -117,14 +117,19 @@ public class MockMyFacesClient
     
     public void ajax(UIComponent source, String event, String execute, String render, boolean submit) throws Exception
     {
+        ajax(source, event, execute, render, submit, false);
+    }
+            
+    public void ajax(UIComponent source, String event, String execute, String render, boolean submit, boolean resetValues) throws Exception
+    {
         testCase.processRemainingPhases();
-        this.internalAjax(source, event, execute, render, submit);
+        this.internalAjax(source, event, execute, render, submit, resetValues);
         String viewId = facesContext.getViewRoot().getViewId();
         testCase.tearDownRequest();
         testCase.setupRequest(viewId);
     }
     
-    public void internalAjax(UIComponent source, String event, String execute, String render, boolean submit)
+    protected void internalAjax(UIComponent source, String event, String execute, String render, boolean submit, boolean resetValues)
     {
         parameters.put("javax.faces.partial.ajax", "true");
         parameters.put("javax.faces.behavior.event", event);
@@ -150,6 +155,11 @@ public class MockMyFacesClient
             parameters.put(source.getClientId(facesContext), source.getClientId(facesContext));
         }
         
+        if (resetValues)
+        {
+            parameters.put("javax.faces.partial.resetValues", "true");
+        }
+        
         MockHttpServletResponse response = (MockHttpServletResponse) facesContext.getExternalContext().getResponse(); 
         Cookie cookie = response.getCookie("oam.Flash.RENDERMAP.TOKEN");
         getCookies().put("oam.Flash.RENDERMAP.TOKEN", cookie);

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreTestCase.java?rev=1520036&r1=1520035&r2=1520036&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/CoreTestCase.java Wed Sep  4 14:43:42 2013
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.view.facelets.tag.jsf.core;
 
+import org.apache.myfaces.view.facelets.tag.jsf.core.reset.ResetValuesBean;
 import java.util.Date;
 import java.util.Locale;
 import java.util.Map;
@@ -33,6 +34,7 @@ import javax.faces.component.UIInput;
 import javax.faces.component.UIOutput;
 import javax.faces.component.UIPanel;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlCommandButton;
 import javax.faces.component.html.HtmlCommandLink;
 import javax.faces.component.html.HtmlDataTable;
 import javax.faces.component.html.HtmlForm;
@@ -41,11 +43,13 @@ import javax.faces.component.html.HtmlIn
 import javax.faces.component.html.HtmlOutputText;
 import javax.faces.convert.DateTimeConverter;
 import javax.faces.convert.NumberConverter;
+import javax.faces.event.ActionEvent;
 import javax.faces.event.ActionListener;
 import javax.faces.validator.DoubleRangeValidator;
 import javax.faces.validator.LengthValidator;
 import javax.faces.validator.LongRangeValidator;
 import javax.faces.validator.Validator;
+import org.apache.myfaces.renderkit.html.HtmlButtonRenderer;
 
 import org.apache.myfaces.renderkit.html.HtmlFormRenderer;
 import org.apache.myfaces.renderkit.html.HtmlImageRenderer;
@@ -68,6 +72,8 @@ public class CoreTestCase extends Facele
                 UIPanel.class.getName());
         application.addComponent(HtmlCommandLink.COMPONENT_TYPE,
                 HtmlCommandLink.class.getName());
+        application.addComponent(HtmlCommandButton.COMPONENT_TYPE,
+                HtmlCommandButton.class.getName());
         application.addComponent(HtmlGraphicImage.COMPONENT_TYPE,
                 HtmlGraphicImage.class.getName());
         application.addComponent(HtmlForm.COMPONENT_TYPE, HtmlForm.class
@@ -110,6 +116,9 @@ public class CoreTestCase extends Facele
                 new HtmlFormRenderer());
         renderKit.addRenderer(UIData.COMPONENT_FAMILY, "javax.faces.Table",
                 new HtmlTableRenderer());
+        renderKit.addRenderer(UICommand.COMPONENT_FAMILY, "javax.faces.Button",
+                new HtmlButtonRenderer());
+        
     }
 
     @Test
@@ -376,5 +385,43 @@ public class CoreTestCase extends Facele
 
         Assert.assertEquals("german locale", Locale.GERMAN, root.getLocale());
     }
+    
+    @Test
+    public void testResetValuesActionListenerHandler() throws Exception
+    {
+        ResetValuesBean bean = new ResetValuesBean();
+
+        facesContext.getExternalContext().getRequestMap().put("bean", bean);
+        bean.setField1("Hello");
+        bean.setField2(2);
+
+        UIViewRoot root = facesContext.getViewRoot();
+        vdl.buildView(facesContext, root, "resetValuesActionListener_1.xhtml");
+
+        UICommand action1 = (UICommand) root.findComponent("mainForm:submit");
+
+        Assert.assertNotNull("mainForm:submit", action1);
+
+        Assert.assertEquals("mainForm:submit listeners", 1,
+                action1.getActionListeners().length);
+
+        UIInput field1 = (UIInput) root.findComponent("mainForm:field1");
+        field1.setValue("xxx");
+        Assert.assertEquals("xxx", field1.getValue());
+        Assert.assertTrue(field1.isLocalValueSet());
+        
+        UIInput field2 = (UIInput) root.findComponent("mainForm:field2");
+        field2.setSubmittedValue("1");
+        field2.setValid(false);
+        
+        action1.getActionListeners()[0].processAction(new ActionEvent(action1));
+        
+        // If resetValues() was activated, 
+        Assert.assertEquals("Hello",field1.getValue());
+        Assert.assertFalse(field1.isLocalValueSet());
+        Assert.assertNull(field2.getSubmittedValue());
+        Assert.assertTrue(field2.isValid());
+    }
+
 
 }

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java?rev=1520036&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java Wed Sep  4 14:43:42 2013
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.jsf.core.reset;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+import javax.faces.event.ActionEvent;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+@ManagedBean(name="bean")
+@SessionScoped
+public class ResetValuesBean
+{
+    
+    private String field1;
+    
+    private Integer field2;
+
+    public void overrideField1(ActionEvent evt)
+    {
+        field1 = "overriden";
+    }
+    
+    /**
+     * @return the field1
+     */
+    public String getField1()
+    {
+        return field1;
+    }
+
+    /**
+     * @param field1 the field1 to set
+     */
+    public void setField1(String field1)
+    {
+        this.field1 = field1;
+    }
+
+    /**
+     * @return the field2
+     */
+    public Integer getField2()
+    {
+        return field2;
+    }
+
+    /**
+     * @param field2 the field2 to set
+     */
+    public void setField2(Integer field2)
+    {
+        this.field2 = field2;
+    }
+    
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java?rev=1520036&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java Wed Sep  4 14:43:42 2013
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.jsf.core.reset;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIViewRoot;
+import junit.framework.Assert;
+import org.apache.myfaces.mc.test.core.AbstractMyFacesRequestTestCase;
+import org.junit.Test;
+
+/**
+ *
+ * @author lu4242
+ */
+public class ResetValuesTestCase extends AbstractMyFacesRequestTestCase
+{
+    
+    @Override
+    protected boolean isScanAnnotations()
+    {
+        return true;
+    }
+    
+    @Override
+    protected void setUpWebConfigParams() throws Exception
+    {
+        super.setUpWebConfigParams();
+        servletContext.addInitParameter("org.apache.myfaces.annotation.SCAN_PACKAGES","org.apache.myfaces.view.facelets.tag.jsf.core.reset");
+    }
+
+    @Test
+    public void testResetValuesActionListenerHandler2() throws Exception
+    {
+        setupRequest("/resetValuesActionListener_2.xhtml");
+
+        processLifecycleExecute();
+        
+        ResetValuesBean bean = facesContext.getApplication().evaluateExpressionGet(facesContext, 
+            "#{bean}", ResetValuesBean.class);
+        
+        bean.setField1("Hello");
+        bean.setField2(1);
+        
+        executeBuildViewCycle(facesContext);
+                
+        UIComponent submitButton = facesContext.getViewRoot().findComponent("mainForm:submit");
+        
+        UIInput field1 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field1");
+        UIInput field2 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field2");
+        
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
+        
+        // The lenght validator for field1 force a minimum of
+        // 4 digits, but the entered text has only 3 charactes.
+        // In the ajax request, that force a validation error, so
+        // the submitted values are not updated into the model
+        // but if the submitted value is set, it will render "xxx"
+        // and "2". Reset values clear the submitted values and
+        // let what's in the model.
+        client.inputText(field1, "xxx");
+        client.inputText(field2, "2");
+        
+        client.ajax(submitButton, "action", 
+            submitButton.getClientId(facesContext) +" "+
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), 
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), true, true);
+        
+        processLifecycleExecute();
+        processRender();
+
+        field1 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field1");
+        field2 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field2");
+        
+        Assert.assertEquals("Hello", field1.getValue());
+        Assert.assertEquals(1, field2.getValue());
+        Assert.assertNull(field1.getSubmittedValue());
+        Assert.assertNull(field2.getSubmittedValue());
+        
+        Assert.assertEquals("Hello", bean.getField1());
+        Assert.assertEquals(Integer.valueOf(1), bean.getField2());
+
+        //Now let's try the normal way with no resetValues
+        client.inputText(field1, "xxx");
+        client.inputText(field2, "2");
+        
+        client.ajax(submitButton, "action", 
+            submitButton.getClientId(facesContext) +" "+
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), 
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), true, false);
+        
+        processLifecycleExecute();
+        processRender();
+
+        field1 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field1");
+        field2 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field2");
+        
+        // The values in the model are kept but the submitted values are there
+        // and the renderer takes them.
+        Assert.assertEquals("Hello", field1.getValue());
+        // the second field doesn't have validation error!, but the local value
+        // is set with 2, but the model still is 1 because update model phase
+        // was not executed.
+        Assert.assertEquals(2, field2.getValue());
+        Assert.assertTrue(field2.isLocalValueSet());
+        Assert.assertEquals("xxx", field1.getSubmittedValue());
+        Assert.assertNull(field2.getSubmittedValue());
+        
+        Assert.assertEquals("Hello", bean.getField1());
+        Assert.assertEquals(Integer.valueOf(1), bean.getField2());
+        
+        // Now let's try a valid one, in this case the model is updated
+        client.inputText(field1, "xxxx");
+        client.inputText(field2, "3");
+        
+        client.ajax(submitButton, "action", 
+            submitButton.getClientId(facesContext) +" "+
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), 
+            field1.getClientId(facesContext) + " "+ 
+            field2.getClientId(facesContext), true, true);
+        
+        processLifecycleExecute();
+        processRender();
+
+        field1 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field1");
+        field2 = (UIInput) facesContext.getViewRoot().findComponent("mainForm:field2");
+        
+        Assert.assertEquals("xxxx", field1.getValue());
+        Assert.assertEquals(3, field2.getValue());
+        Assert.assertNull(field1.getSubmittedValue());
+        Assert.assertNull(field2.getSubmittedValue());
+        
+        Assert.assertEquals("xxxx", bean.getField1());
+        Assert.assertEquals(Integer.valueOf(3), bean.getField2());
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/jsf/core/reset/ResetValuesTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml?rev=1520036&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml Wed Sep  4 14:43:42 2013
@@ -0,0 +1,29 @@
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id: actionListener.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+             xmlns:h="http://java.sun.com/jsf/html"
+             xmlns:f="http://java.sun.com/jsf/core"
+             xmlns:ui="http://java.sun.com/jsf/facelets">
+    <h:form id="mainForm">
+        <h:inputText id="field1" value="#{bean.field1}">
+            <f:validateLength minimum="4"/>
+        </h:inputText>
+        <h:inputText id="field2" value="#{bean.field2}"/>
+        <h:commandButton id="submit" value="Submit">
+            <f:ajax resetValues="true" render="field1 mainForm:field2"/>
+        </h:commandButton>
+    </h:form>
+</ui:composition>
\ No newline at end of file

Propchange: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/reset/resetValuesActionListener_2.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml?rev=1520036&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml Wed Sep  4 14:43:42 2013
@@ -0,0 +1,27 @@
+<!--
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id: actionListener.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+             xmlns:h="http://java.sun.com/jsf/html"
+             xmlns:f="http://java.sun.com/jsf/core"
+             xmlns:ui="http://java.sun.com/jsf/facelets">
+    <h:form id="mainForm">
+        <h:inputText id="field1" value="#{bean.field1}"/>
+        <h:inputText id="field2" value="#{bean.field2}"/>
+        <h:commandButton id="submit" value="Submit">
+            <f:resetValues render="field1 mainForm:field2"/>
+        </h:commandButton>
+    </h:form>
+</ui:composition>
\ No newline at end of file

Propchange: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/jsf/core/resetValuesActionListener_1.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native