Util.checkIdUniqueness(context,
viewRoot,
new HashSet<String>(viewRoot.getChildCount() << 1));
final Map<String,Object> stateMap = new HashMap<String,Object>();
final StateContext stateContext = StateContext.getStateContext(context);
// PENDING: This is included for those component frameworks that don't utilize the
// new VisitHint(s) yet - but still wish to know that they should be non-iterating
// during state saving. It should be removed at some point.
context.getAttributes().put(SKIP_ITERATION_HINT, true);
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_ITERATION);
VisitContext visitContext = VisitContext.createVisitContext(context, null, hints);
final FacesContext finalContext = context;
try {
viewRoot.visitTree(visitContext, new VisitCallback() {
public VisitResult visit(VisitContext context, UIComponent target) {
VisitResult result = VisitResult.ACCEPT;
Object stateObj;
if (!target.isTransient()) {
if (stateContext.componentAddedDynamically(target)) {
stateObj = new StateHolderSaver(finalContext, target);
Map<String, ComponentStruct> dynamicAdds = stateContext.getDynamicAdds();
assert(null != dynamicAdds);
String clientId = target.getClientId(finalContext);
if (!dynamicAdds.containsKey(clientId)) {
ComponentStruct toAdd = new ComponentStruct();
toAdd.absorbComponent(finalContext, target);
dynamicAdds.put(clientId, toAdd);
}
} else {
stateObj = target.saveState(context.getFacesContext());
}
if (null != stateObj) {
stateMap.put(target.getClientId(context.getFacesContext()), stateObj);
}
} else {
return result;
}
return result;
}
});
} finally {
// PENDING: This is included for those component frameworks that don't utilize the
// new VisitHint(s) yet - but still wish to know that they should be non-iterating
// during state saving. It should be removed at some point.
context.getAttributes().remove(SKIP_ITERATION_HINT);
}
// handle dynamic adds/removes
List<String> removeList = stateContext.getDynamicRemoves();
if (null != removeList && !removeList.isEmpty()) {
stateMap.put(CLIENTIDS_TO_REMOVE_NAME, removeList);
}
Map<String, ComponentStruct> addList = stateContext.getDynamicAdds();
if (null != addList && !addList.isEmpty()) {
List<Object> savedAddList = new ArrayList<Object>(addList.size());
for (ComponentStruct s : addList.values()) {
savedAddList.add(s.saveState(context));
}