You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2022/12/19 15:16:18 UTC
[myfaces] branch main updated: MYFACES-4537
This is an automated email from the ASF dual-hosted git repository.
tandraschko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/main by this push:
new b71508c8d MYFACES-4537
b71508c8d is described below
commit b71508c8d8d6da2e7b975270fcd1b8c7ec2df8ec
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Mon Dec 19 16:16:10 2022 +0100
MYFACES-4537
---
.../view/facelets/tag/faces/core/AjaxHandler.java | 146 +++++++++------------
.../html/behavior/AjaxBehaviorRenderTestCase.java | 19 ++-
.../myfaces/renderkit/html/behavior/ajax_7.xhtml | 36 +++++
3 files changed, 118 insertions(+), 83 deletions(-)
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/faces/core/AjaxHandler.java b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/faces/core/AjaxHandler.java
index a5ae7e69c..ce2872bd6 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/faces/core/AjaxHandler.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/faces/core/AjaxHandler.java
@@ -98,62 +98,61 @@ public class AjaxHandler extends TagHandler implements
@JSFFaceletAttribute(name = "disabled", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.Boolean")
- private final TagAttribute _disabled;
+ private final TagAttribute disabled;
@JSFFaceletAttribute(name = "event", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.String")
- private final TagAttribute _event;
+ private final TagAttribute event;
@JSFFaceletAttribute(name = "execute", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.Object")
- private final TagAttribute _execute;
+ private final TagAttribute execute;
@JSFFaceletAttribute(name = "immediate", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.Boolean")
- private final TagAttribute _immediate;
+ private final TagAttribute immediate;
@JSFFaceletAttribute(name = "listener", className = "jakarta.el.MethodExpression",
deferredMethodSignature = "public void m(jakarta.faces.event.AjaxBehaviorEvent evt) "
+ "throws jakarta.faces.event.AbortProcessingException")
- private final TagAttribute _listener;
-
+ private final TagAttribute listener;
@JSFFaceletAttribute(name = "onevent", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.String")
- private final TagAttribute _onevent;
-
+ private final TagAttribute onevent;
@JSFFaceletAttribute(name = "onerror", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.String")
- private final TagAttribute _onerror;
+ private final TagAttribute onerror;
@JSFFaceletAttribute(name = "render", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.Object")
- private final TagAttribute _render;
+ private final TagAttribute render;
@JSFFaceletAttribute(name = "delay", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.String")
- private final TagAttribute _delay;
+ private final TagAttribute delay;
@JSFFaceletAttribute(name = "resetValues", className = "jakarta.el.ValueExpression",
deferredValueType = "java.lang.Boolean")
- private final TagAttribute _resetValues;
+ private final TagAttribute resetValues;
- private final boolean _wrapMode;
+ private final boolean wrappingMode;
public AjaxHandler(TagConfig config)
{
super(config);
- _disabled = getAttribute("disabled");
- _event = getAttribute("event");
- _execute = getAttribute("execute");
- _immediate = getAttribute("immediate");
- _listener = getAttribute("listener");
- _onerror = getAttribute("onerror");
- _onevent = getAttribute("onevent");
- _render = getAttribute("render");
- _delay = getAttribute("delay");
- _resetValues = getAttribute("resetValues");
+ disabled = getAttribute("disabled");
+ event = getAttribute("event");
+ execute = getAttribute("execute");
+ immediate = getAttribute("immediate");
+ listener = getAttribute("listener");
+ onerror = getAttribute("onerror");
+ onevent = getAttribute("onevent");
+ render = getAttribute("render");
+ delay = getAttribute("delay");
+ resetValues = getAttribute("resetValues");
+
// According to the spec, this tag works in two different ways:
// 1. Apply an ajax behavior for a selected component in this way
// <x:component><f:ajax ..../></x:component>
@@ -167,47 +166,36 @@ public class AjaxHandler extends TagHandler implements
// <composite:interface> handler: traverse the tree for instances of
// ComponentHandler. If it is found, wrapMode is used otherwise
// suppose f:ajax is the one wrapped by a component.
- Collection<FaceletHandler> compHandlerList =
- TagHandlerUtils.findNextByType(nextHandler, ComponentHandler.class,
- InsertChildrenHandler.class, InsertHandler.class, DecorateHandler.class, IncludeHandler.class);
-
- _wrapMode = !compHandlerList.isEmpty();
+ Collection<FaceletHandler> compHandlerList = TagHandlerUtils.findNextByType(nextHandler,
+ ComponentHandler.class, InsertChildrenHandler.class, InsertHandler.class,
+ DecorateHandler.class, IncludeHandler.class);
+ wrappingMode = !compHandlerList.isEmpty();
}
@Override
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException
{
- //Apply only if we are creating a new component
- if (!ComponentHandler.isNew(parent))
- {
- if (_wrapMode)
- {
- AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
- // In this case it will be only applied to components inserted by
- // c:if or related tags, in other cases, ComponentTagHandlerDelegate should
- // not reapply ajax tag.
- actx.pushAjaxHandlerToStack(this);
- nextHandler.apply(ctx, parent);
- actx.popAjaxHandlerToStack();
- }
- return;
- }
- if (_wrapMode)
+ if (wrappingMode)
{
AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
- // Push and pop this ajax handler to the stack, to delegate the
- // call to applyAttachedObject to ComponentTagHandlerDelegate
- // The default one proposed here is
- // use a different stack on DefaultFaceletContext.applyCompositeComponent,
- // so components inside composite:implementation tag will not be
- // affected by f:ajax outsider handlers.
+ // In this case it will be only applied to components inserted by
+ // c:if or related tags, in other cases, ComponentTagHandlerDelegate should
+ // not reapply ajax tag.
actx.pushAjaxHandlerToStack(this);
nextHandler.apply(ctx, parent);
actx.popAjaxHandlerToStack();
+
+ registerFacesJsResource(ctx, parent);
}
else
{
+ //Apply only if we are creating a new component
+ if (!ComponentHandler.isNew(parent))
+ {
+ return;
+ }
+
if (parent instanceof ClientBehaviorHolder)
{
//Apply this handler directly over the parent
@@ -229,12 +217,11 @@ public class AjaxHandler extends TagHandler implements
else
{
throw new TagException(this.tag,
- "Parent is not composite component or of type ClientBehaviorHolder, type is: "
- + parent);
+ "Parent is not composite component or of type ClientBehaviorHolder; Type is: " + parent);
}
+
+ registerFacesJsResource(ctx, parent);
}
-
- registerFacesJsResource(ctx, parent);
}
public static void registerFacesJsResource(FaceletContext ctx, UIComponent parent)
@@ -284,21 +271,21 @@ public class AjaxHandler extends TagHandler implements
@Override
public String getEventName()
{
- if (_event == null)
+ if (event == null)
{
return null;
}
else
{
- if (_event.isLiteral())
+ if (event.isLiteral())
{
- return _event.getValue();
+ return event.getValue();
}
else
{
FaceletContext faceletContext = (FaceletContext) FacesContext.getCurrentInstance().
getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
- return (String) _event.getValueExpression(faceletContext, String.class).getValue(faceletContext);
+ return (String) event.getValueExpression(faceletContext, String.class).getValue(faceletContext);
}
}
}
@@ -319,15 +306,15 @@ public class AjaxHandler extends TagHandler implements
ClientBehaviorHolder cvh = (ClientBehaviorHolder) parent;
String eventName = null;
- if (_event != null)
+ if (event != null)
{
- if (_event.isLiteral())
+ if (event.isLiteral())
{
- eventName = _event.getValue();
+ eventName = event.getValue();
}
else
{
- eventName = (String) _event.getValueExpression(faceletContext, String.class).getValue(faceletContext);
+ eventName = (String) event.getValueExpression(faceletContext, String.class).getValue(faceletContext);
}
}
if (eventName == null)
@@ -335,7 +322,7 @@ public class AjaxHandler extends TagHandler implements
eventName = cvh.getDefaultEventName();
if (eventName == null)
{
- if (_wrapMode)
+ if (wrappingMode)
{
// No eventName defined, we can't apply this tag to this component, because
// there is no event defined to attach it, but since we are in wrap mode
@@ -345,14 +332,14 @@ public class AjaxHandler extends TagHandler implements
}
else
{
- throw new TagAttributeException(_event,
+ throw new TagAttributeException(event,
"eventName could not be defined for f:ajax tag with no wrap mode.");
}
}
}
else if (!cvh.getEventNames().contains(eventName))
{
- if (_wrapMode)
+ if (wrappingMode)
{
// The current component does not implement the event selected,
// this ajax behavior cannot be applied, but we can't throw any exception
@@ -362,23 +349,23 @@ public class AjaxHandler extends TagHandler implements
}
else
{
- throw new TagAttributeException(_event,
+ throw new TagAttributeException(event,
"event it is not a valid eventName defined for this component");
}
}
- AjaxBehavior ajaxBehavior = createBehavior(context);
- setAttribute(faceletContext, ajaxBehavior, _disabled, Boolean.class, (v) -> ajaxBehavior.setDisabled(v));
- setAttribute(faceletContext, ajaxBehavior, _execute, Object.class);
- setAttribute(faceletContext, ajaxBehavior, _immediate, Boolean.class, (v) -> ajaxBehavior.setImmediate(v));
- setAttribute(faceletContext, ajaxBehavior, _onerror, String.class, (v) -> ajaxBehavior.setOnerror(v));
- setAttribute(faceletContext, ajaxBehavior, _onevent, String.class, (v) -> ajaxBehavior.setOnevent(v));
- setAttribute(faceletContext, ajaxBehavior, _render, Object.class);
- setAttribute(faceletContext, ajaxBehavior, _delay, String.class, (v) -> ajaxBehavior.setDelay(v));
- setAttribute(faceletContext, ajaxBehavior, _resetValues, Boolean.class, (v) -> ajaxBehavior.setResetValues(v));
- if (_listener != null)
+ AjaxBehavior ajaxBehavior = (AjaxBehavior) context.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
+ setAttribute(faceletContext, ajaxBehavior, disabled, Boolean.class, (v) -> ajaxBehavior.setDisabled(v));
+ setAttribute(faceletContext, ajaxBehavior, execute, Object.class);
+ setAttribute(faceletContext, ajaxBehavior, immediate, Boolean.class, (v) -> ajaxBehavior.setImmediate(v));
+ setAttribute(faceletContext, ajaxBehavior, onerror, String.class, (v) -> ajaxBehavior.setOnerror(v));
+ setAttribute(faceletContext, ajaxBehavior, onevent, String.class, (v) -> ajaxBehavior.setOnevent(v));
+ setAttribute(faceletContext, ajaxBehavior, render, Object.class);
+ setAttribute(faceletContext, ajaxBehavior, delay, String.class, (v) -> ajaxBehavior.setDelay(v));
+ setAttribute(faceletContext, ajaxBehavior, resetValues, Boolean.class, (v) -> ajaxBehavior.setResetValues(v));
+ if (listener != null)
{
- MethodExpression expr = _listener.getMethodExpression(
+ MethodExpression expr = listener.getMethodExpression(
faceletContext, Void.TYPE, AJAX_BEHAVIOR_LISTENER_SIG);
AjaxBehaviorListener abl = new AjaxBehaviorListenerImpl(expr);
ajaxBehavior.addAjaxBehaviorListener(abl);
@@ -441,11 +428,6 @@ public class AjaxHandler extends TagHandler implements
}
}
}
-
- protected AjaxBehavior createBehavior(FacesContext context)
- {
- return (AjaxBehavior) context.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
- }
/**
* The documentation says this attribute should not be used since it is not
diff --git a/impl/src/test/java/org/apache/myfaces/renderkit/html/behavior/AjaxBehaviorRenderTestCase.java b/impl/src/test/java/org/apache/myfaces/renderkit/html/behavior/AjaxBehaviorRenderTestCase.java
index 6871c1e88..e8d8c5675 100644
--- a/impl/src/test/java/org/apache/myfaces/renderkit/html/behavior/AjaxBehaviorRenderTestCase.java
+++ b/impl/src/test/java/org/apache/myfaces/renderkit/html/behavior/AjaxBehaviorRenderTestCase.java
@@ -24,7 +24,6 @@ import jakarta.faces.application.ViewHandler;
import jakarta.faces.component.UIViewRoot;
import org.apache.myfaces.test.mock.MockResponseWriter;
-import org.apache.myfaces.util.lang.StringUtils;
import org.apache.myfaces.view.facelets.FaceletTestCase;
import org.junit.Test;
@@ -133,6 +132,24 @@ public class AjaxBehaviorRenderTestCase extends FaceletTestCase {
assertTrue(response.contains("myfaces.ab"));
}
+ @Test
+ public void testAjax7() throws Exception {
+ UIViewRoot root = facesContext.getViewRoot();
+ vdl.buildView(facesContext, root, "ajax_7.xhtml");
+
+ StringWriter sw = new StringWriter();
+ MockResponseWriter mrw = new MockResponseWriter(sw);
+ facesContext.setResponseWriter(mrw);
+ root.encodeAll(facesContext);
+ sw.flush();
+
+ String response = sw.toString();
+ assertTrue(response.contains("myfaces.ab"));
+ assertTrue(response.contains("faces.util.chain"));
+ assertEquals(countMatches(response, "faces.util.chain"), 1);
+ assertEquals(countMatches(response, "myfaces.ab"), 2);
+ }
+
public int countMatches(String all, String search)
{
return all.split(search, -1).length - 1;
diff --git a/impl/src/test/resources/org/apache/myfaces/renderkit/html/behavior/ajax_7.xhtml b/impl/src/test/resources/org/apache/myfaces/renderkit/html/behavior/ajax_7.xhtml
new file mode 100644
index 000000000..55aee81c6
--- /dev/null
+++ b/impl/src/test/resources/org/apache/myfaces/renderkit/html/behavior/ajax_7.xhtml
@@ -0,0 +1,36 @@
+<!--
+ * 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.
+ *
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html">
+ <body>
+ <h:form id="form" >
+ <!-- Test one: No behaviors rendered -->
+ <f:ajax execute="@all" render="@all">
+ <h:inputText id="input">
+ <f:ajax execute="@this" render="@all"/>
+ </h:inputText>
+ </f:ajax>
+ <br/>
+ </h:form>
+ </body>
+</html>