Skip to content

Commit

Permalink
PartialViewContextImpl should use same VisitContext to reset values as
Browse files Browse the repository at this point in the history
the one used to process the execute and render
#5396
  • Loading branch information
BalusC committed Feb 10, 2024
1 parent 8e914f1 commit 190cce9
Showing 1 changed file with 27 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import jakarta.faces.FacesException;
import jakarta.faces.FactoryFinder;
import jakarta.faces.application.ResourceHandler;
import jakarta.faces.component.EditableValueHolder;
import jakarta.faces.component.NamingContainer;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.UIViewRoot;
Expand Down Expand Up @@ -284,7 +285,7 @@ public void processPartial(PhaseId phaseId) {
writer.startDocument();

if (isResetValues()) {
viewRoot.resetValues(ctx, myRenderIds);
resetValues(viewRoot, myRenderIds, ctx);
}

if (isRenderAll()) {
Expand Down Expand Up @@ -379,11 +380,8 @@ private void processComponents(UIComponent component, PhaseId phaseId, Collectio
// We use the tree visitor mechanism to locate the components to
// process. Create our (partial) VisitContext and the
// VisitCallback that will be invoked for each component that
// is visited. Note that we use the SKIP_UNRENDERED hint as we
// only want to visit the rendered subtree.
EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED, VisitHint.EXECUTE_LIFECYCLE);
VisitContextFactory visitContextFactory = (VisitContextFactory) FactoryFinder.getFactory(VISIT_CONTEXT_FACTORY);
VisitContext visitContext = visitContextFactory.getVisitContext(context, phaseClientIds, hints);
// is visited.
VisitContext visitContext = createPartialVisitContext(context, phaseClientIds);
PhaseAwareVisitCallback visitCallback = new PhaseAwareVisitCallback(ctx, phaseId);
component.visitTree(visitContext, visitCallback);

Expand All @@ -400,6 +398,29 @@ private void processComponents(UIComponent component, PhaseId phaseId, Collectio
}
}

private static VisitContext createPartialVisitContext(FacesContext context, Collection<String> clientIds) {

// Note that we use the SKIP_UNRENDERED hint as
// we only want to visit the rendered subtree.
EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED, VisitHint.EXECUTE_LIFECYCLE);
VisitContextFactory visitContextFactory = (VisitContextFactory) FactoryFinder.getFactory(VISIT_CONTEXT_FACTORY);
return visitContextFactory.getVisitContext(context, clientIds, hints);
}

private static void resetValues(UIComponent component, Collection<String> clientIds, FacesContext context) {
component.visitTree(createPartialVisitContext(context, clientIds), new DoResetValues());
}

private static class DoResetValues implements VisitCallback {
@Override
public VisitResult visit(VisitContext context, UIComponent target) {
if (target instanceof EditableValueHolder) {
((EditableValueHolder) target).resetValue();
}
return VisitResult.ACCEPT;
}
}

/**
* Unwraps {@link PartialVisitContext} from a chain of {@link VisitContextWrapper}s.
*
Expand Down

0 comments on commit 190cce9

Please sign in to comment.