Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -178,70 +178,6 @@ private void captureRest(List<TreeNode> tree, int pos, UIComponent c) {
}
}

/**
* Find the given component in the component tree.
*
* @param context the Faces context.
* @param clientId the client id of the component to find.
*/
private UIComponent locateComponentByClientId(final FacesContext context, final UIComponent subTree, final String clientId) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "FaceletFullStateManagementStrategy.locateComponentByClientId", clientId);
}

final List<UIComponent> found = new ArrayList<UIComponent>();
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, new VisitCallback() {

public VisitResult visit(VisitContext visitContext, UIComponent component) {
VisitResult result = VisitResult.ACCEPT;
if (component.getClientId(visitContext.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result = VisitResult.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(visitContext.getFacesContext()))) {
result = VisitResult.REJECT;
}
} else if (component instanceof NamingContainer
&& !clientId.startsWith(component.getClientId(visitContext.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.
*/
result = VisitResult.REJECT;
}

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

if (!found.isEmpty()) {
result = found.get(0);
}
return result;
}

/**
* Create a new component instance.
*
Expand Down Expand Up @@ -378,15 +314,33 @@ private void restoreDynamicActions(FacesContext context, StateContext stateConte
List<Object> savedActions = (List<Object>) viewRoot.getAttributes().get(DYNAMIC_ACTIONS);
List<ComponentStruct> actions = stateContext.getDynamicActions();

final Map<String, UIComponent> compCache = new HashMap<>();
try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
context.getViewRoot().visitTree(visitContext, new VisitCallback() {

@Override
public VisitResult visit(VisitContext visitContext, UIComponent component) {
compCache.put(component.getClientId(visitContext.getFacesContext()), component);
return VisitResult.ACCEPT;
}

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

if (savedActions != null && !savedActions.isEmpty()) {
for (Object object : savedActions) {
ComponentStruct action = new ComponentStruct();
action.restoreState(context, object);
if (ComponentStruct.ADD.equals(action.action)) {
restoreDynamicAdd(context, state, action);
restoreDynamicAdd(context, state, action, compCache);
}
if (ComponentStruct.REMOVE.equals(action.action)) {
restoreDynamicRemove(context, action);
restoreDynamicRemove(context, action, compCache);
}
pruneAndReAddToDynamicActions(actions, action);
}
Expand All @@ -400,15 +354,15 @@ private void restoreDynamicActions(FacesContext context, StateContext stateConte
* @param state the state.
* @param struct the component struct.
*/
private void restoreDynamicAdd(FacesContext context, Map<String, Object> state, ComponentStruct struct) {
private void restoreDynamicAdd(FacesContext context, Map<String, Object> state, ComponentStruct struct, Map<String, UIComponent> compCache) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("FaceletFullStateManagementStrategy.restoreDynamicAdd");
}

UIComponent parent = locateComponentByClientId(context, context.getViewRoot(), struct.parentClientId);
UIComponent parent = compCache.get(struct.parentClientId);

if (parent != null) {
UIComponent child = locateComponentByClientId(context, parent, struct.clientId);
UIComponent child = compCache.get(struct.clientId);

/*
* If Facelets engine restored the child before us we are going to
Expand Down Expand Up @@ -465,6 +419,7 @@ private void restoreDynamicAdd(FacesContext context, Map<String, Object> state,
}
child.getAttributes().put(DYNAMIC_COMPONENT, child.getParent().getChildren().indexOf(child));
stateContext.getDynamicComponents().put(struct.clientId, child);
compCache.put(struct.clientId, child);
}
}
}
Expand All @@ -475,17 +430,18 @@ private void restoreDynamicAdd(FacesContext context, Map<String, Object> state,
* @param context the Faces context.
* @param struct the component struct.
*/
private void restoreDynamicRemove(FacesContext context, ComponentStruct struct) {
private void restoreDynamicRemove(FacesContext context, ComponentStruct struct, Map<String, UIComponent> compCache) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("FaceletFullStateManagementStrategy.restoreDynamicRemove");
}

UIComponent child = locateComponentByClientId(context, context.getViewRoot(), struct.clientId);
UIComponent child = compCache.get(struct.clientId);
if (child != null) {
StateContext stateContext = StateContext.getStateContext(context);
stateContext.getDynamicComponents().put(struct.clientId, child);
UIComponent parent = child.getParent();
parent.getChildren().remove(child);
compCache.remove(struct.clientId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,70 +101,6 @@ public FaceletPartialStateManagementStrategy() {
public FaceletPartialStateManagementStrategy(FacesContext context) {
}

/**
* Find the given component in the component tree.
*
* @param context the Faces context.
* @param clientId the client id of the component to find.
*/
private UIComponent locateComponentByClientId(final FacesContext context, final UIComponent subTree, final String clientId) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "FaceletPartialStateManagementStrategy.locateComponentByClientId", clientId);
}

final List<UIComponent> found = new ArrayList<UIComponent>();
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, new VisitCallback() {

public VisitResult visit(VisitContext visitContext, UIComponent component) {
VisitResult result = VisitResult.ACCEPT;
if (component.getClientId(visitContext.getFacesContext()).equals(clientId)) {
/*
* If the client id matches up we have found our match.
*/
found.add(component);
result = VisitResult.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(visitContext.getFacesContext()))) {
result = VisitResult.REJECT;
}
} else if (component instanceof NamingContainer &&
!clientId.startsWith(component.getClientId(visitContext.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.
*/
result = VisitResult.REJECT;
}

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

if (!found.isEmpty()) {
result = found.get(0);
}
return result;
}

/**
* Methods that takes care of pruning and re-adding an action to the dynamic
* action list.
Expand Down Expand Up @@ -218,15 +154,32 @@ private void restoreDynamicActions(FacesContext context, StateContext stateConte
List<Object> savedActions = (List<Object>) stateMap.get(DYNAMIC_ACTIONS);
List<ComponentStruct> actions = stateContext.getDynamicActions();

final Map<String, UIComponent> compCache = new HashMap<>();
try {
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
context.getViewRoot().visitTree(visitContext, new VisitCallback() {

@Override
public VisitResult visit(VisitContext visitContext, UIComponent component) {
compCache.put(component.getClientId(visitContext.getFacesContext()), component);
return VisitResult.ACCEPT;
}
});
} finally {
context.getAttributes().remove(SKIP_ITERATION_HINT);
}

if (savedActions != null && !savedActions.isEmpty()) {
for (Object object : savedActions) {
ComponentStruct action = new ComponentStruct();
action.restoreState(context, object);
if (ComponentStruct.ADD.equals(action.action)) {
restoreDynamicAdd(context, stateMap, action);
restoreDynamicAdd(context, stateMap, action, compCache);
}
if (ComponentStruct.REMOVE.equals(action.action)) {
restoreDynamicRemove(context, action);
restoreDynamicRemove(context, action, compCache);
}
pruneAndReAddToDynamicActions(actions, action);
}
Expand All @@ -240,15 +193,15 @@ private void restoreDynamicActions(FacesContext context, StateContext stateConte
* @param state the state.
* @param struct the component struct.
*/
private void restoreDynamicAdd(FacesContext context, Map<String, Object> state, ComponentStruct struct) {
private void restoreDynamicAdd(FacesContext context, Map<String, Object> state, ComponentStruct struct, Map<String, UIComponent> compCache) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("FaceletPartialStateManagementStrategy.restoreDynamicAdd");
}

UIComponent parent = locateComponentByClientId(context, context.getViewRoot(), struct.parentClientId);
UIComponent parent = compCache.get(struct.parentClientId);

if (parent != null) {
UIComponent child = locateComponentByClientId(context, parent, struct.clientId);
UIComponent child = compCache.get(struct.clientId);

/*
* If Facelets engine restored the child before us we are going to
Expand Down Expand Up @@ -305,6 +258,7 @@ private void restoreDynamicAdd(FacesContext context, Map<String, Object> state,
}
child.getAttributes().put(DYNAMIC_COMPONENT, child.getParent().getChildren().indexOf(child));
stateContext.getDynamicComponents().put(struct.clientId, child);
compCache.put(struct.clientId, child);
}
}
}
Expand All @@ -315,17 +269,18 @@ private void restoreDynamicAdd(FacesContext context, Map<String, Object> state,
* @param context the Faces context.
* @param struct the component struct.
*/
private void restoreDynamicRemove(FacesContext context, ComponentStruct struct) {
private void restoreDynamicRemove(FacesContext context, ComponentStruct struct, Map<String, UIComponent> compCache) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("FaceletPartialStateManagementStrategy.restoreDynamicRemove");
}

UIComponent child = locateComponentByClientId(context, context.getViewRoot(), struct.clientId);
UIComponent child = compCache.get(struct.clientId);
if (child != null) {
StateContext stateContext = StateContext.getStateContext(context);
stateContext.getDynamicComponents().put(struct.clientId, child);
UIComponent parent = child.getParent();
parent.getChildren().remove(child);
compCache.remove(struct.clientId);
}
}

Expand Down Expand Up @@ -417,7 +372,7 @@ private void saveDynamicActions(FacesContext context, StateContext stateContext,

List<ComponentStruct> actions = stateContext.getDynamicActions();
HashMap<String, UIComponent> componentMap = stateContext.getDynamicComponents();

if (actions != null) {
List<Object> savedActions = new ArrayList<Object>(actions.size());
for (ComponentStruct action : actions) {
Expand Down
Loading