jakarta.faces.component.visit.VisitContext Maven / Gradle / Ivy
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package jakarta.faces.component.visit;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import jakarta.faces.FactoryFinder;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
/**
*
*
* A context object that is used to hold state relating to performing a component tree visit.
*
*
*
*
*
* Component tree visits are initiated by calling {@link UIComponent#visitTree}, at which point both a
* {@link VisitContext} and a {@link VisitCallback} must be provided.
*
*
*
* @see UIComponent#visitTree UIComponent.visitTree()
* @see VisitCallback
*
* @since 2.0
*/
abstract public class VisitContext {
// Design notes: The VisitContext contract could be defined
// as an interface. However, there is the potential that we
// may need to add new methods in the future, so leaving as
// an abstract class in order to have room to grow.
//
// Since we are an abstract class rather than an interface,
// we could provide implementations of of some of the simpler
// methods (eg. getFacesContext() and getHints()) to avoid
// duplicating this code in VisitContext implementations.
// However, doing so would mean that "wrapping" VisitContext
// implementations would be forced to pick up such implementations,
// so going with a pure contract (no implementation).
/**
*
* This unmodifiable Collection is returned by getIdsToVisit()
and getSubtreeIdsToVisit()
in
* cases where all ids should be visited.
*
*
*
* To simplify logic for visitTree()
implementations, this Collection always returns false
for
* isEmpty
. All other methods throw UnsupportedOperationException
.
*
*
* @since 2.0
*/
// Note: We cannot use Collections.emptyList() as that returns
// a shared instance - we want to unique instance to allow for
// identity tests.
static public final Collection ALL_IDS = new AbstractCollection() {
@Override
public Iterator iterator() {
throw new UnsupportedOperationException("VisitContext.ALL_IDS does not support this operation");
}
@Override
public int size() {
throw new UnsupportedOperationException("VisitContext.ALL_IDS does not support this operation");
}
@Override
public boolean isEmpty() {
return false;
}
};
/**
*
* Returns the FacesContext for the current request.
*
*
* @return the FacesContext.
*
* @since 2.0
*/
abstract public FacesContext getFacesContext();
/**
*
* Returns the ids of the components to visit.
*
*
*
* In the case of a full tree visit, this method returns the ALL_IDS collection. Otherwise, if a partial visit is beign
* performed, returns a modifiable collection containing the client ids of the components that should be visited.
*
*
* @return the ids of the components to visit
*
*/
abstract public Collection getIdsToVisit();
/**
*
* Given a {@link jakarta.faces.component.NamingContainer} component, returns the client ids of any components
* underneath the NamingContainer that should be visited.
*
*
*
*
*
* This method is called by NamingContainer visitTree() implementations to determine whether the NamingContainer
* contains components to be visited. In the case where no such components exist, the NamingContainer can short-circuit
* the tree visit and avoid descending into child subtrees.
*
*
*
* In addition, iterating components such as UIData may be able to use the returned ids to determine which iterated
* states (ie. rows) need to be visited. This allows the visit traversal to be contstrained such only those rows that
* contain visit targets need to be traversed.
*
*
*
*
* @param component a NamingContainer component
* @return an unmodifiable Collection containing the client ids of any components underneath the NamingContainer that
* are known to be targets of the tree visit. If no such components exist, returns an empty Collection. If all
* components underneath the NamingContainer should be visited, returns the {@code VisitContext.ALL_IDS} collection.
* @throws IllegalArgumentException if {@code component} is not an instance of NamingContainer
*/
abstract public Collection getSubtreeIdsToVisit(UIComponent component);
/**
*
* Called by {@link UIComponent#visitTree UIComponent.visitTree()} to visit a single component.
*
*
* @param component the component to visit
* @param callback the VisitCallback to call
* @return a VisitResult value that indicates whether to continue visiting the component's subtree, skip visiting the
* component's subtree or abort the visit altogether.
*/
abstract public VisitResult invokeVisitCallback(UIComponent component, VisitCallback callback);
/**
*
* Returns hints that influence the behavior of the tree visit.
*
*
*
* Interested parties, such as {@link UIComponent#visitTree UIComponent.visitTree()} implementations, may check to see
* whether a particular hint is present by calling {@code VisitContext.getHints().contains()}, passing in one of the
* hints defined by {@link VisitHint}.
*
* @return a non-empty, unmodifiable collection of VisitHints
*/
abstract public Set getHints();
/**
*
* Returns a VisitContext instance that is initialized with the specified ids and hintsfor use with
* {@link UIComponent#visitTree}.
*
*
* @param context the FacesContext for the current request
* @param ids the client ids of the components to visit. If null, all components will be visited.
* @param hints the VisitHints to apply to the visit. If null
, no hints are applied.
*
* @return a VisitContext instance that is initialized with the specified ids and hints.
*/
public static VisitContext createVisitContext(FacesContext context, Collection ids, Set hints) {
VisitContextFactory factory = (VisitContextFactory) FactoryFinder.getFactory(FactoryFinder.VISIT_CONTEXT_FACTORY);
return factory.getVisitContext(context, ids, hints);
}
/**
*
* Creates a VisitContext instance for use with {@link UIComponent#visitTree UIComponent.visitTree()}. This method can
* be used to obtain a VisitContext instance when all components should be visited with the default visit hints.
*
*
* @param context the FacesContext for the current request
* @return a VisitContext instance
*/
public static VisitContext createVisitContext(FacesContext context) {
return createVisitContext(context, null, null);
}
}