Skip to content

Commit

Permalink
Backport f:ajax execute/render=@this to 2.3; all tests passed localhost
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Apr 18, 2021
1 parent 539e1ae commit df9997a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public List<UIComponent> getTargets(UIComponent topLevelComponent) {
void setTargetsList(ValueExpression targetsList) {
this.targetsList = targetsList;
}

ValueExpression getTargetsList() {
return targetsList;
}


// if the current composite component ID is the same as the target ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public List<UIComponent> getTargets(UIComponent topLevelComponent) {
List<UIComponent> wrappedTargets = new ArrayList<>(targets.size());
for (UIComponent component : targets) {
wrappedTargets
.add(new BehaviorHolderWrapper(component, getName(), getEvent()));
.add(new BehaviorHolderWrapper(component, getName(), getEvent(), super.getTargetsList()));
}
return wrappedTargets;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ public class BehaviorHolderWrapper extends UIComponent implements
private final UIComponent parent;
private final String virtualEvent;
private final String event;
private final ValueExpression targets;

public BehaviorHolderWrapper(UIComponent parent, String virtualEvent, String event) {
public BehaviorHolderWrapper(UIComponent parent, String virtualEvent, String event, ValueExpression targets) {
this.parent = parent;
this.virtualEvent = virtualEvent;
this.event = event;
this.targets = targets;
}

/**
Expand Down Expand Up @@ -475,5 +477,8 @@ public Collection<String> getEventNames() {
return Collections.singleton(virtualEvent);
}

public ValueExpression getTargets() {
return targets;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

package com.sun.faces.facelets.tag.jsf.core;

import static java.util.Arrays.stream;
import static javax.faces.component.UINamingContainer.getSeparatorChar;

import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
Expand All @@ -28,6 +32,7 @@
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.el.MethodNotFoundException;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.application.ResourceHandler;
import javax.faces.component.UIComponent;
Expand All @@ -50,6 +55,7 @@

import com.sun.faces.component.behavior.AjaxBehaviors;
import com.sun.faces.facelets.tag.TagHandlerImpl;
import com.sun.faces.facelets.tag.composite.BehaviorHolderWrapper;
import com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler;
import com.sun.faces.renderkit.RenderKitUtils;

Expand Down Expand Up @@ -195,7 +201,7 @@ private void applyWrapping(FaceletContext ctx,
// is going to be Ajax enabled and install the Ajax resource.
RenderKitUtils.installJsfJsIfNecessary(ctx.getFacesContext());

AjaxBehavior ajaxBehavior = createAjaxBehavior(ctx, eventName);
AjaxBehavior ajaxBehavior = createAjaxBehavior(ctx, parent, eventName);

// We leverage AjaxBehaviors to support the wrapping case. We
// push/pop the AjaxBehavior instance on AjaxBehaviors so that
Expand Down Expand Up @@ -305,13 +311,13 @@ private void applyAttachedObject(FaceletContext ctx,
}
}

AjaxBehavior ajaxBehavior = createAjaxBehavior(ctx, eventName);
AjaxBehavior ajaxBehavior = createAjaxBehavior(ctx, parent, eventName);
bHolder.addClientBehavior(eventName, ajaxBehavior);
RenderKitUtils.installJsfJsIfNecessary(ctx.getFacesContext());
}

// Construct our AjaxBehavior from tag parameters.
private AjaxBehavior createAjaxBehavior(FaceletContext ctx, String eventName) {
private AjaxBehavior createAjaxBehavior(FaceletContext ctx, UIComponent parent, String eventName) {
Application application = ctx.getFacesContext().getApplication();
AjaxBehavior behavior = (AjaxBehavior)application.createBehavior(
AjaxBehavior.BEHAVIOR_ID);
Expand All @@ -325,6 +331,25 @@ private AjaxBehavior createAjaxBehavior(FaceletContext ctx, String eventName) {
setBehaviorAttribute(ctx, behavior, this.render, Object.class);
setBehaviorAttribute(ctx, behavior, this.delay, String.class);

if (parent instanceof BehaviorHolderWrapper) {
ValueExpression targets = ((BehaviorHolderWrapper) parent).getTargets();

if (targets != null) {
String targetClientIds = (String) targets.getValue(ctx);

if (targetClientIds != null) {
Collection<String> executeClientIds = new ArrayList<>(behavior.getExecute());

if (executeClientIds.isEmpty() || executeClientIds.contains("@this")) {
String separatorChar = String.valueOf(getSeparatorChar(ctx.getFacesContext()));
executeClientIds.remove("@this");
stream(targetClientIds.trim().split(" +")).map(id -> "@this" + separatorChar + id).forEach(executeClientIds::add);
behavior.setExecute(executeClientIds);
}
}
}
}

if (null != listener) {
behavior.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(
this.listener.getMethodExpression(ctx, Object.class, new Class[] { AjaxBehaviorEvent.class }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.sun.faces.renderkit.html_basic;

import static javax.faces.component.UINamingContainer.getSeparatorChar;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
Expand Down Expand Up @@ -315,8 +317,13 @@ private static void appendIds(FacesContext facesContext,

boolean first = true;

UIComponent composite = UIComponent.getCompositeComponentParent(component);
String separatorChar = String.valueOf(getSeparatorChar(facesContext));

for (String id : ids) {
if (id.trim().length() == 0) {
String expression = id.trim();

if (expression.length() == 0) {
continue;
}
if (!first) {
Expand All @@ -325,9 +332,15 @@ private static void appendIds(FacesContext facesContext,
first = false;
}

if (id.equals("@all") || id.equals("@none") ||
id.equals("@form") || id.equals("@this")) {
builder.append(id);
boolean clientResolveableExpression = expression.equals("@all") || expression.equals("@none") || expression.equals("@form") || expression.equals("@this");

if (composite != null && expression.startsWith("@this" + separatorChar)) {
expression = expression.replaceFirst("@this", separatorChar + composite.getClientId(facesContext));
clientResolveableExpression = false;
}

if (clientResolveableExpression) {
builder.append(expression);
} else {
if (searchExpressionContext == null) {
searchExpressionContext = SearchExpressionContext.createSearchExpressionContext(
Expand All @@ -338,9 +351,19 @@ private static void appendIds(FacesContext facesContext,
}
String resolvedClientId = null;
try {
resolvedClientId = handler.resolveClientId(searchExpressionContext, id);
resolvedClientId = handler.resolveClientId(searchExpressionContext, expression);
} catch (ComponentNotFoundException cnfe) {
resolvedClientId = getResolvedId(component, id);
if (composite != null && !expression.startsWith(separatorChar) && composite.getParent() != null && composite.getParent().getNamingContainer() != null) {
expression = composite.getParent().getNamingContainer().getClientId(facesContext) + separatorChar + expression;

try {
resolvedClientId = handler.resolveClientId(searchExpressionContext, expression);
} catch (ComponentNotFoundException ignore) {
resolvedClientId = getResolvedId(component, expression);
}
} else {
resolvedClientId = getResolvedId(component, expression);
}
}
builder.append(resolvedClientId);
}
Expand Down

0 comments on commit df9997a

Please sign in to comment.