/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asual.summer.ajax; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.faces.component.UIComponent; import javax.faces.component.visit.VisitCallback; import javax.faces.component.visit.VisitHint; import javax.faces.component.visit.VisitResult; import javax.faces.context.FacesContext; import com.sun.faces.component.visit.PartialVisitContext; /** * * @author Rostislav Hristov * */ public class AjaxVisitContext extends PartialVisitContext { private Collection<String> unknownClientIds; private Collection<String> unvisitedClientIds; private Map<String,Collection<String>> subtreeClientIds; public AjaxVisitContext(Collection<String> clientIds, Set<VisitHint> hints) { super(FacesContext.getCurrentInstance(), clientIds, hints); unknownClientIds = new HashSet<String>(); unvisitedClientIds = new HashSet<String>(clientIds); subtreeClientIds = new HashMap<String,Collection<String>>(); for (String id : unvisitedClientIds) { UIComponent component = findComponent(id, FacesContext.getCurrentInstance().getViewRoot()); if (component != null) { String clientId = component.getClientId(); while (component != null) { subtreeClientIds.put(component.getClientId(), Arrays.asList(clientId)); component = component.getParent(); } } else { unknownClientIds.add(id); } } } public VisitResult invokeVisitCallback(UIComponent component, VisitCallback callback) { String clientId = component.getClientId(); if (!unvisitedClientIds.contains(clientId)) { clientId = null; return VisitResult.ACCEPT; } VisitResult result = callback.visit(this, component); unvisitedClientIds.remove(clientId); unknownClientIds.remove(clientId); if (unvisitedClientIds.isEmpty()) { return VisitResult.COMPLETE; } return result; } private UIComponent findComponent(String expr, UIComponent component) { if (expr.equals(component.getClientId())) { return component; } UIComponent result = null; Iterator<UIComponent> children = component.getFacetsAndChildren(); while(children.hasNext()) { UIComponent child = children.next(); result = findComponent(expr, child); if (result != null) { return result; } } return result; } public Collection<String> getSubtreeIdsToVisit(UIComponent component) { if (unknownClientIds.size() != 0) { return unvisitedClientIds; } Collection<String> subtreeIdsToVisit = subtreeClientIds.get(component.getClientId()); if (subtreeIdsToVisit != null) { return subtreeIdsToVisit; } else { return Arrays.asList(); } } }