Skip to content

Commit

Permalink
Merge 2.3 into 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Sep 7, 2023
2 parents 5649a0c + a86a228 commit 93ecf20
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -938,13 +938,16 @@ public void broadcast(FacesEvent event) throws AbortProcessingException {
FacesEvent target = idxEvent.getTarget();
FacesContext ctx = target.getFacesContext();
resetDataModel(ctx);
int prevIndex = index;
int idx = idxEvent.getIndex();
int prevIndex = this.index;
boolean needsToSetIndex = idx != -1 || prevIndex != -1; // #5213
UIComponent source = target.getComponent();
UIComponent compositeParent = null;
try {
int rowCount = getDataModel().getRowCount();
int idx = idxEvent.getIndex();
setIndex(ctx, idx);
if (needsToSetIndex) {
setIndex(ctx, idx);
}
Integer begin = getBegin();
Integer end = getEnd();
Integer step = getStep();
Expand All @@ -969,7 +972,9 @@ public void broadcast(FacesEvent event) throws AbortProcessingException {
compositeParent.popComponentFromEL(ctx);
}
updateIterationStatus(ctx, null);
setIndex(ctx, prevIndex);
if (needsToSetIndex) {
setIndex(ctx, prevIndex);
}
}
} else {
super.broadcast(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private class RelocateChildrenListener extends RelocateListener {
this.ctx = ctx;
this.component = component;
if (!component.getAttributes().containsKey(INDEX_ATTRIBUTE)) {
component.getAttributes().put(INDEX_ATTRIBUTE, idx); // NOTE: this is also used by AjaxBehaviorRenderer in order to detect if f:ajax was handled by cc:insertChildren. See also #5032
component.getAttributes().put(INDEX_ATTRIBUTE, idx);
}
this.idx = idx;
this.location = location;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package com.sun.faces.facelets.tag.composite;

import java.util.Collection;
import java.util.Set;

import jakarta.el.ValueExpression;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.behavior.AjaxBehavior;
import jakarta.faces.component.behavior.ClientBehaviorContext;
import jakarta.faces.component.behavior.ClientBehaviorHint;
import jakarta.faces.context.FacesContext;
import jakarta.faces.event.AbortProcessingException;
import jakarta.faces.event.AjaxBehaviorListener;
import jakarta.faces.event.BehaviorEvent;

/**
* Basically represents <f:ajax> which is retargeted by <cc:clientBehavior> in AjaxHandler and checked in AjaxBehaviorRenderer.
*
* We should probably introduce AjaxBehaviorWrapper in Faces.next to reduce boilerplate like this.
*
* @see https://github.com/jakartaee/faces/issues/1567
* @see https://github.com/eclipse-ee4j/mojarra/issues/5032
*/
public class RetargetedAjaxBehavior extends AjaxBehavior {

private AjaxBehavior retargeted;

public RetargetedAjaxBehavior(AjaxBehavior retargeted) {
this.retargeted = retargeted;
}

@Override
public String getScript(ClientBehaviorContext behaviorContext) {
return retargeted.getScript(behaviorContext);
}

@Override
public void broadcast(BehaviorEvent event) throws AbortProcessingException {
retargeted.broadcast(event);
}

@Override
public int hashCode() {
return retargeted.hashCode();
}

@Override
public String getRendererType() {
return retargeted.getRendererType();
}

@Override
public void decode(FacesContext context, UIComponent component) {
retargeted.decode(context, component);
}

@Override
public boolean isTransient() {
return retargeted.isTransient();
}

@Override
public Set<ClientBehaviorHint> getHints() {
return retargeted.getHints();
}

@Override
public void setTransient(boolean transientFlag) {
retargeted.setTransient(transientFlag);
}

@Override
public String getOnerror() {
return retargeted.getOnerror();
}

@Override
public void setOnerror(String onerror) {
retargeted.setOnerror(onerror);
}

@Override
public boolean equals(Object obj) {
return retargeted.equals(obj);
}

@Override
public String getOnevent() {
return retargeted.getOnevent();
}

@Override
public void setOnevent(String onevent) {
retargeted.setOnevent(onevent);
}

@Override
public void markInitialState() {
retargeted.markInitialState();
}

@Override
public boolean initialStateMarked() {
return retargeted.initialStateMarked();
}

@Override
public Collection<String> getExecute() {
return retargeted.getExecute();
}

@Override
public void clearInitialState() {
retargeted.clearInitialState();
}

@Override
public void setExecute(Collection<String> execute) {
retargeted.setExecute(execute);
}

@Override
public String getDelay() {
return retargeted.getDelay();
}

@Override
public void setDelay(String delay) {
retargeted.setDelay(delay);
}

@Override
public Collection<String> getRender() {
return retargeted.getRender();
}

@Override
public void setRender(Collection<String> render) {
retargeted.setRender(render);
}

@Override
public boolean isResetValues() {
return retargeted.isResetValues();
}

@Override
public void setResetValues(boolean resetValues) {
retargeted.setResetValues(resetValues);
}

@Override
public boolean isDisabled() {
return retargeted.isDisabled();
}

@Override
public void setDisabled(boolean disabled) {
retargeted.setDisabled(disabled);
}

@Override
public boolean isImmediate() {
return retargeted.isImmediate();
}

@Override
public void setImmediate(boolean immediate) {
retargeted.setImmediate(immediate);
}

@Override
public boolean isImmediateSet() {
return retargeted.isImmediateSet();
}

@Override
public String toString() {
return retargeted.toString();
}

@Override
public boolean isResetValuesSet() {
return retargeted.isResetValuesSet();
}

@Override
public ValueExpression getValueExpression(String name) {
return retargeted.getValueExpression(name);
}

@Override
public void setValueExpression(String name, ValueExpression binding) {
retargeted.setValueExpression(name, binding);
}

@Override
public void addAjaxBehaviorListener(AjaxBehaviorListener listener) {
retargeted.addAjaxBehaviorListener(listener);
}

@Override
public void removeAjaxBehaviorListener(AjaxBehaviorListener listener) {
retargeted.removeAjaxBehaviorListener(listener);
}

@Override
public Object saveState(FacesContext context) {
return retargeted.saveState(context);
}

@Override
public void restoreState(FacesContext context, Object state) {
retargeted.restoreState(context, state);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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.composite.RetargetedAjaxBehavior;
import com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler;
import com.sun.faces.renderkit.RenderKitUtils;

Expand Down Expand Up @@ -315,6 +316,7 @@ private AjaxBehavior createAjaxBehavior(FaceletContext ctx, UIComponent parent,
executeClientIds.remove("@this");
stream(targetClientIds.trim().split(" +")).map(id -> "@this" + separatorChar + id).forEach(executeClientIds::add);
behavior.setExecute(executeClientIds);
behavior = new RetargetedAjaxBehavior(behavior);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.faces.facelets.tag.composite.InsertChildrenHandler;
import com.sun.faces.facelets.tag.composite.RetargetedAjaxBehavior;
import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.util.FacesLogger;

Expand Down Expand Up @@ -221,9 +221,9 @@ private static String buildAjaxCommand(ClientBehaviorContext behaviorContext, Aj
ajaxCommand.append(eventName);
ajaxCommand.append("',");

appendIds(behaviorContext.getFacesContext(), component, ajaxCommand, execute);
appendIds(behaviorContext.getFacesContext(), component, ajaxBehavior, ajaxCommand, execute);
ajaxCommand.append(",");
appendIds(behaviorContext.getFacesContext(), component, ajaxCommand, render);
appendIds(behaviorContext.getFacesContext(), component, ajaxBehavior, ajaxCommand, render);

if (onevent != null || onerror != null || delay != null || resetValues != null || !params.isEmpty()) {

Expand Down Expand Up @@ -280,7 +280,7 @@ private static String buildAjaxCommand(ClientBehaviorContext behaviorContext, Aj
SearchExpressionHint.RESOLVE_SINGLE_COMPONENT);

// Appends an ids argument to the ajax command
private static void appendIds(FacesContext facesContext, UIComponent component, StringBuilder builder, Collection<String> ids) {
private static void appendIds(FacesContext facesContext, UIComponent component, AjaxBehavior ajaxBehavior, StringBuilder builder, Collection<String> ids) {

if (null == ids || ids.isEmpty()) {
builder.append('0');
Expand All @@ -294,7 +294,7 @@ private static void appendIds(FacesContext facesContext, UIComponent component,

boolean first = true;

UIComponent composite = UIComponent.getCompositeComponentParent(component);
UIComponent composite = (ajaxBehavior instanceof RetargetedAjaxBehavior) ? UIComponent.getCompositeComponentParent(component) : null;
String separatorChar = String.valueOf(getSeparatorChar(facesContext));

for (String id : ids) {
Expand All @@ -311,7 +311,7 @@ private static void appendIds(FacesContext facesContext, UIComponent component,

boolean clientResolveableExpression = expression.equals("@all") || expression.equals("@none") || expression.equals("@form") || expression.equals("@this");

if (composite != null && !isHandledByInsertChildren(component, composite) && (expression.equals("@this") || expression.startsWith("@this" + separatorChar))) {
if (composite != null && (expression.equals("@this") || expression.startsWith("@this" + separatorChar))) {
expression = expression.replaceFirst("@this", separatorChar + composite.getClientId(facesContext));
clientResolveableExpression = false;
}
Expand Down Expand Up @@ -347,16 +347,6 @@ private static void appendIds(FacesContext facesContext, UIComponent component,
builder.append("'");
}

private static boolean isHandledByInsertChildren(UIComponent component, UIComponent composite) {
for (UIComponent parent = component.getParent(); parent != null && !parent.equals(composite); parent = parent.getParent()) {
if (parent.getAttributes().containsKey(InsertChildrenHandler.INDEX_ATTRIBUTE)) {
return true;
}
}

return false;
}

// Returns the resolved (client id) for a particular id.
private static String getResolvedId(UIComponent component, String id) {

Expand Down
14 changes: 11 additions & 3 deletions impl/src/main/java/jakarta/faces/component/UIData.java
Original file line number Diff line number Diff line change
Expand Up @@ -1051,8 +1051,14 @@ public void broadcast(FacesEvent event) throws AbortProcessingException {
if (isNestedWithinIterator(context)) {
setDataModel(null);
}
int oldRowIndex = getRowIndex();
setRowIndex(revent.getRowIndex());
int currentRowIndex = getRowIndex();
int broadcastedRowIndex = revent.getRowIndex();
boolean needsToSetIndex = currentRowIndex != -1 || broadcastedRowIndex != -1; // #5213

if (needsToSetIndex) {
setRowIndex(broadcastedRowIndex);
}

FacesEvent rowEvent = revent.getFacesEvent();
UIComponent source = rowEvent.getComponent();
UIComponent compositeParent = null;
Expand All @@ -1071,8 +1077,10 @@ public void broadcast(FacesEvent event) throws AbortProcessingException {
compositeParent.popComponentFromEL(context);
}
}
setRowIndex(oldRowIndex);

if (needsToSetIndex) {
setRowIndex(currentRowIndex);
}
}

/**
Expand Down

0 comments on commit 93ecf20

Please sign in to comment.