Skip to content

Commit

Permalink
Merge #5355 from 4.1 into 5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Dec 2, 2023
2 parents 26914a8 + bc447bc commit 1d23288
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public class FaceletFullStateManagementStrategy extends StateManagementStrategy
/**
* Stores the skip hint.
*/
private static final String SKIP_ITERATION_HINT = "jakarta.faces.visit.SKIP_ITERATION";
private static final Set<VisitHint> SKIP_ITERATION_HINT = EnumSet.of(SKIP_ITERATION);

/**
* Stores the class map.
Expand Down Expand Up @@ -185,41 +185,34 @@ private UIComponent locateComponentByClientId(final FacesContext context, final
final List<UIComponent> found = new ArrayList<>();
UIComponent result = null;

try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);

VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
subTree.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result1 = ACCEPT;
if (component.getClientId(visitContext1.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result1 = COMPLETE;
} else if (component instanceof UIForm) {
/*
* If the component is a UIForm and it is prepending its id then we can short circuit out of here if the the client id
* of the component we are trying to find does not begin with the id of the UIForm.
*/
UIForm form = (UIForm) component;
if (form.isPrependId() && !clientId.startsWith(form.getClientId(visitContext1.getFacesContext()))) {
result1 = REJECT;
}
} else if (component instanceof NamingContainer && !clientId.startsWith(component.getClientId(visitContext1.getFacesContext()))) {
/*
* If the component is a naming container then assume it is prepending its id so if our client id we are looking for
* does not start with the naming container id we can skip visiting this tree.
*/
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);
subTree.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result1 = ACCEPT;
if (component.getClientId(visitContext1.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result1 = COMPLETE;
} else if (component instanceof UIForm) {
/*
* If the component is a UIForm and it is prepending its id then we can short circuit out of here if the the client id
* of the component we are trying to find does not begin with the id of the UIForm.
*/
UIForm form = (UIForm) component;
if (form.isPrependId() && !clientId.startsWith(form.getClientId(visitContext1.getFacesContext()))) {
result1 = REJECT;
}
} else if (component instanceof NamingContainer && !clientId.startsWith(component.getClientId(visitContext1.getFacesContext()))) {
/*
* If the component is a naming container then assume it is prepending its id so if our client id we are looking for
* does not start with the naming container id we can skip visiting this tree.
*/
result1 = REJECT;
}

return result1;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
return result1;
});

if (!found.isEmpty()) {
result = found.get(0);
Expand Down Expand Up @@ -311,36 +304,30 @@ private void restoreComponentState(final FacesContext context, final HashMap<Str
final StateContext stateContext = StateContext.getStateContext(context);
final UIViewRoot viewRoot = context.getViewRoot();

try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);

viewRoot.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result = ACCEPT;
viewRoot.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result = ACCEPT;

String clientId = component.getClientId(context);
Object stateObj = state.get(clientId);
String clientId = component.getClientId(context);
Object stateObj = state.get(clientId);

if (stateObj != null && !stateContext.componentAddedDynamically(component)) {
boolean restoreStateNow = true;
if (stateObj instanceof StateHolderSaver) {
restoreStateNow = !((StateHolderSaver) stateObj).componentAddedDynamically();
}
if (restoreStateNow) {
try {
component.restoreState(context, stateObj);
} catch (Exception e) {
throw new FacesException(e);
}
if (stateObj != null && !stateContext.componentAddedDynamically(component)) {
boolean restoreStateNow = true;
if (stateObj instanceof StateHolderSaver) {
restoreStateNow = !((StateHolderSaver) stateObj).componentAddedDynamically();
}
if (restoreStateNow) {
try {
component.restoreState(context, stateObj);
} catch (Exception e) {
throw new FacesException(e);
}
}
}

return result;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
return result;
});
}

/**
Expand Down Expand Up @@ -592,33 +579,27 @@ private Object saveComponentState(FacesContext context) {
final UIViewRoot viewRoot = context.getViewRoot();
final FacesContext finalContext = context;

context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);

try {
viewRoot.visitTree(visitContext, (context1, component) -> {
VisitResult result = ACCEPT;
Object stateObj;
if (!component.isTransient()) {
if (stateContext.componentAddedDynamically(component)) {
component.getAttributes().put(DYNAMIC_COMPONENT, new Integer(getProperChildIndex(component)));
stateObj = new StateHolderSaver(finalContext, component);
} else {
stateObj = component.saveState(finalContext);
}
if (stateObj != null) {
stateMap.put(component.getClientId(finalContext), stateObj);
}
viewRoot.visitTree(visitContext, (context1, component) -> {
VisitResult result = ACCEPT;
Object stateObj;
if (!component.isTransient()) {
if (stateContext.componentAddedDynamically(component)) {
component.getAttributes().put(DYNAMIC_COMPONENT, new Integer(getProperChildIndex(component)));
stateObj = new StateHolderSaver(finalContext, component);
} else {
result = REJECT;
stateObj = component.saveState(finalContext);
}
if (stateObj != null) {
stateMap.put(component.getClientId(finalContext), stateObj);
}
} else {
result = REJECT;
}

return result;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
return result;
});

return stateMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,16 @@ public class FaceletPartialStateManagementStrategy extends StateManagementStrate
* Stores the logger.
*/
private static final Logger LOGGER = FacesLogger.APPLICATION_VIEW.getLogger();

/**
* Stores the skip hint.
*/
private static final String SKIP_ITERATION_HINT = "jakarta.faces.visit.SKIP_ITERATION";
private static final Set<VisitHint> SKIP_ITERATION_HINT = EnumSet.of(SKIP_ITERATION);

/**
* Stores the skip and lifecycle hints.
*/
private static final Set<VisitHint> SKIP_ITERATION_AND_EXECUTE_LIFECYCLE_HINTS = EnumSet.of(VisitHint.SKIP_ITERATION, VisitHint.EXECUTE_LIFECYCLE);

/**
* Constructor.
Expand Down Expand Up @@ -102,41 +108,34 @@ private UIComponent locateComponentByClientId(final FacesContext context, final
final List<UIComponent> found = new ArrayList<>();
UIComponent result = null;

try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(SKIP_ITERATION);

VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
subTree.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result1 = ACCEPT;
if (component.getClientId(visitContext1.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result1 = COMPLETE;
} else if (component instanceof UIForm) {
/*
* If the component is a UIForm and it is prepending its id then we can short circuit out of here if the the client id
* of the component we are trying to find does not begin with the id of the UIForm.
*/
UIForm form = (UIForm) component;
if (form.isPrependId() && !clientId.startsWith(form.getClientId(visitContext1.getFacesContext()))) {
result1 = REJECT;
}
} else if (component instanceof NamingContainer && !clientId.startsWith(component.getClientId(visitContext1.getFacesContext()))) {
/*
* If the component is a naming container then assume it is prepending its id so if our client id we are looking for
* does not start with the naming container id we can skip visiting this tree.
*/
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);
subTree.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result1 = ACCEPT;
if (component.getClientId(visitContext1.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result1 = COMPLETE;
} else if (component instanceof UIForm) {
/*
* If the component is a UIForm and it is prepending its id then we can short circuit out of here if the the client id
* of the component we are trying to find does not begin with the id of the UIForm.
*/
UIForm form = (UIForm) component;
if (form.isPrependId() && !clientId.startsWith(form.getClientId(visitContext1.getFacesContext()))) {
result1 = REJECT;
}
} else if (component instanceof NamingContainer && !clientId.startsWith(component.getClientId(visitContext1.getFacesContext()))) {
/*
* If the component is a naming container then assume it is prepending its id so if our client id we are looking for
* does not start with the naming container id we can skip visiting this tree.
*/
result1 = REJECT;
}

return result1;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
return result1;
});

if (!found.isEmpty()) {
result = found.get(0);
Expand Down Expand Up @@ -343,9 +342,7 @@ public UIViewRoot restoreView(FacesContext context, String viewId, String render
try {
stateContext.setTrackViewModifications(false);

context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION, VisitHint.EXECUTE_LIFECYCLE);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_AND_EXECUTE_LIFECYCLE_HINTS);
viewRoot.visitTree(visitContext, (context1, target) -> {
VisitResult result = VisitResult.ACCEPT;
String cid = target.getClientId(context1.getFacesContext());
Expand All @@ -370,7 +367,6 @@ public UIViewRoot restoreView(FacesContext context, String viewId, String render
restoreDynamicActions(context, stateContext, state);
} finally {
stateContext.setTrackViewModifications(true);
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
} else {
viewRoot = null;
Expand Down Expand Up @@ -436,33 +432,27 @@ public Object saveView(FacesContext context) {
final Map<String, Object> stateMap = new HashMap<>();
final StateContext stateContext = StateContext.getStateContext(context);

context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);
final FacesContext finalContext = context;

try {
viewRoot.visitTree(visitContext, (context1, target) -> {
VisitResult result = VisitResult.ACCEPT;
Object stateObj;
if (!target.isTransient()) {
if (stateContext.componentAddedDynamically(target)) {
target.getAttributes().put(DYNAMIC_COMPONENT, target.getParent().getChildren().indexOf(target));
stateObj = new StateHolderSaver(finalContext, target);
} else {
stateObj = target.saveState(context1.getFacesContext());
}
if (stateObj != null) {
stateMap.put(target.getClientId(context1.getFacesContext()), stateObj);
}
viewRoot.visitTree(visitContext, (context1, target) -> {
VisitResult result = VisitResult.ACCEPT;
Object stateObj;
if (!target.isTransient()) {
if (stateContext.componentAddedDynamically(target)) {
target.getAttributes().put(DYNAMIC_COMPONENT, target.getParent().getChildren().indexOf(target));
stateObj = new StateHolderSaver(finalContext, target);
} else {
return VisitResult.REJECT;
stateObj = target.saveState(context1.getFacesContext());
}
return result;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
if (stateObj != null) {
stateMap.put(target.getClientId(context1.getFacesContext()), stateObj);
}
} else {
return VisitResult.REJECT;
}
return result;
});

saveDynamicActions(context, stateContext, stateMap);
StateContext.release(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.sun.faces.application.view;

import static jakarta.faces.component.visit.VisitHint.SKIP_ITERATION;

import java.util.EnumSet;
import java.util.List;
import java.util.Set;
Expand All @@ -41,7 +43,7 @@ class FormOmittedChecker {
/**
* Stores the skip hint.
*/
private static final String SKIP_ITERATION_HINT = "jakarta.faces.visit.SKIP_ITERATION";
private static final Set<VisitHint> SKIP_ITERATION_HINT = EnumSet.of(SKIP_ITERATION);

/**
* Constructor.
Expand All @@ -60,24 +62,17 @@ public static void check(FacesContext context) {
List<UIComponent> children = viewRoot.getChildren();

for (UIComponent child : children) {
try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);

VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
child.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result = VisitResult.ACCEPT;
VisitContext visitContext = VisitContext.createVisitContext(context, null, SKIP_ITERATION_HINT);
child.visitTree(visitContext, (visitContext1, component) -> {
VisitResult result = VisitResult.ACCEPT;

if (isForm(component)) {
result = VisitResult.REJECT;
} else if (isInNeedOfForm(component)) {
addFormOmittedMessage(finalContext, component);
}
return result;
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
if (isForm(component)) {
result = VisitResult.REJECT;
} else if (isInNeedOfForm(component)) {
addFormOmittedMessage(finalContext, component);
}
return result;
});
}
}

Expand Down
Loading

0 comments on commit 1d23288

Please sign in to comment.