Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
Jakarta Faces defines an MVC framework for building user interfaces for web applications,
including UI components, state management, event handing, input validation, page navigation, and
support for internationalization and accessibility.
/*
* Copyright (c) 1997, 2018 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 javax.faces.component;
import static com.sun.faces.util.Util.isAllNull;
import static com.sun.faces.util.Util.isAnyNull;
import static com.sun.faces.util.Util.isEmpty;
import static java.beans.Introspector.getBeanInfo;
import static java.lang.Boolean.TRUE;
import static java.lang.Character.isDigit;
import static java.lang.Character.isLetter;
import static java.lang.Thread.currentThread;
import static java.util.Collections.unmodifiableCollection;
import static java.util.Collections.unmodifiableList;
import static java.util.logging.Level.FINE;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELException;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.component.behavior.Behavior;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.BehaviorEvent;
import javax.faces.event.ComponentSystemEventListener;
import javax.faces.event.FacesEvent;
import javax.faces.event.FacesListener;
import javax.faces.event.PostAddToViewEvent;
import javax.faces.event.PostValidateEvent;
import javax.faces.event.PreRemoveFromViewEvent;
import javax.faces.event.PreRenderComponentEvent;
import javax.faces.event.PreValidateEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.faces.render.Renderer;
import com.sun.faces.application.ValueBindingValueExpressionAdapter;
import com.sun.faces.application.ValueExpressionValueBindingAdapter;
/**
*
* UIComponentBase is a convenience base class that implements the
* default concrete behavior of all methods defined by {@link UIComponent}.
*
*
*
* By default, this class defines getRendersChildren() to find the renderer for this
* component and call its getRendersChildren() method. The default implementation on
* the Renderer returns false. As of version 1.2 of the JavaServer Faces
* Specification, component authors are encouraged to return true from this method and
* rely on the implementation of {@link #encodeChildren} in this class and in the Renderer
* ({@link Renderer#encodeChildren}). Subclasses that wish to manage the rendering of their children
* should override this method to return true instead.
*
*/
public abstract class UIComponentBase extends UIComponent {
// -------------------------------------------------------------- Attributes
private static Logger LOGGER = Logger.getLogger("javax.faces.component", "javax.faces.LogStrings");
private static final String ADDED = UIComponentBase.class.getName() + ".ADDED";
private static final int MY_STATE = 0;
private static final int CHILD_STATE = 1;
/**
*
* Each entry is an map of PropertyDescriptors describing the properties of a
* concrete {@link UIComponent} implementation, keyed by the corresponding
* java.lang.Class.
*
*
*/
private Map, Map> descriptors;
/**
* Reference to the map of PropertyDescriptors for this class in the
* descriptorsMap.
*/
private Map propertyDescriptorMap;
private Map, List> listenersByEventClass;
/**
*
* An EMPTY_OBJECT_ARRAY argument list to be passed to reflection methods.
*
*/
private static final Object EMPTY_OBJECT_ARRAY[] = new Object[0];
/**
*
* The Map containing our attributes, keyed by attribute name.
*
*/
private AttributesMap attributes;
/**
*
* The component identifier for this component.
*
*/
private String id;
/**
*
* The assigned client identifier for this component.
*
*/
private String clientId;
/**
*
* The parent component for this component.
*
*/
private UIComponent parent;
/**
* The List containing our child components.
*/
private List children;
/**
* The Map containing our related facet components.
*/
private Map facets;
private AttachedObjectListHolder listeners;
/**
* Flag indicating a desire to now participate in state saving.
*/
private boolean transientFlag;
public UIComponentBase() {
populateDescriptorsMapIfNecessary();
}
@Override
public Map getAttributes() {
if (attributes == null) {
attributes = new AttributesMap(this);
}
return attributes;
}
@Override
public Map getPassThroughAttributes(boolean create) {
@SuppressWarnings("unchecked")
Map passThroughAttributes = (Map) this.getStateHelper().get(PropertyKeys.passThroughAttributes);
if (passThroughAttributes == null && create) {
passThroughAttributes = new PassThroughAttributesMap<>();
getStateHelper().put(PropertyKeys.passThroughAttributes, passThroughAttributes);
}
return passThroughAttributes;
}
// -------------------------------------------------------------- Properties
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public String getClientId(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// If the clientId is not yet set
if (clientId == null) {
UIComponent namingContainerAncestor = getNamingContainerAncestor();
// Give the parent the opportunity to first grab a unique clientId
String parentId = getParentId(context, namingContainerAncestor);
// Now resolve our own client id
clientId = getId();
if (clientId == null) {
setId(generateId(context, namingContainerAncestor));
clientId = getId();
}
if (parentId != null) {
clientId = addParentId(context, parentId, clientId);
}
// Allow the renderer to convert the clientId
Renderer renderer = getRenderer(context);
if (renderer != null) {
clientId = renderer.convertClientId(context, clientId);
}
}
return clientId;
}
@Override
public String getId() {
return id;
}
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws IllegalStateException {@inheritDoc}
*/
@Override
public void setId(String id) {
// if the current ID is not null, and the passed
// argument is the same, no need to validate it
// as it has already been validated.
if (this.id == null || !(this.id.equals(id))) {
validateId(id);
this.id = id;
}
this.clientId = null; // Erase any cached value
}
@Override
public UIComponent getParent() {
return parent;
}
@Override
public void setParent(UIComponent parent) {
if (parent == null) {
if (this.parent != null) {
doPreRemoveProcessing(FacesContext.getCurrentInstance(), this);
this.parent = parent;
}
compositeParent = null;
} else {
this.parent = parent;
if (getAttributes().get(ADDED) == null) {
// Add an attribute to this component here to indiciate that
// it's being processed. If we don't do this, and the component
// is re-parented, the events could fire again in certain cases
// and cause a stack overflow.
getAttributes().put(ADDED, TRUE);
doPostAddProcessing(FacesContext.getCurrentInstance(), this);
// Remove the attribute once we've returned from the event
// processing.
this.getAttributes().remove(ADDED);
}
}
}
@Override
public boolean isRendered() {
return Boolean.valueOf(getStateHelper().eval(PropertyKeys.rendered, TRUE).toString());
}
@Override
public void setRendered(boolean rendered) {
getStateHelper().put(PropertyKeys.rendered, rendered);
}
@Override
public String getRendererType() {
return (String) getStateHelper().eval(PropertyKeys.rendererType);
}
@Override
public void setRendererType(String rendererType) {
getStateHelper().put(PropertyKeys.rendererType, rendererType);
}
@Override
public boolean getRendersChildren() {
if (getRendererType() != null) {
Renderer renderer = getRenderer(getFacesContext());
if (renderer != null) {
return renderer.getRendersChildren();
}
}
return false;
}
// ------------------------------------------------- Tree Management Methods
@Override
public List getChildren() {
if (children == null) {
children = new ChildrenList(this);
}
return children;
}
// Do not allocate the children List to answer this question
@Override
public int getChildCount() {
if (children != null) {
return children.size();
}
return 0;
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public UIComponent findComponent(String expression) {
if (expression == null) {
throw new NullPointerException();
}
if (expression.isEmpty()) {
// If an empty value is provided, fail fast.
throw new IllegalArgumentException("\"\"");
}
final char sepChar = UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance());
// Identify the base component from which we will perform our search
UIComponent base = findBaseComponent(expression, sepChar);
if (expression.charAt(0) == sepChar) {
// Treat remainder of the expression as relative
expression = expression.substring(1);
}
// Evaluate the search expression (now guaranteed to be relative)
return evaluateSearchExpression(base, expression, String.valueOf(sepChar));
}
/**
* {@inheritDoc}
*
* @throws NullPointerException {@inheritDoc}
* @throws FacesException {@inheritDoc}
* @since 1.2
*/
@Override
public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback) throws FacesException {
return super.invokeOnComponent(context, clientId, callback);
}
// ------------------------------------------------ Facet Management Methods
@Override
public Map getFacets() {
if (facets == null) {
facets = new FacetsMap(this);
}
return facets;
}
// Do not allocate the children List to answer this question
@Override
public int getFacetCount() {
if (facets != null) {
return facets.size();
}
return 0;
}
// Do not allocate the facets Map to answer this question
@Override
public UIComponent getFacet(String name) {
if (facets != null) {
return facets.get(name);
}
return null;
}
@Override
public Iterator getFacetsAndChildren() {
int childCount = getChildCount(), facetCount = getFacetCount();
// If there are neither facets nor children
if (childCount == 0 && facetCount == 0) {
return EMPTY_ITERATOR;
}
// If there are only facets and no children
if (childCount == 0) {
return unmodifiableCollection(getFacets().values()).iterator();
}
// If there are only children and no facets
if (facetCount == 0) {
return unmodifiableList(getChildren()).iterator();
}
// If there are both children and facets
return new FacetsAndChildrenIterator(this);
}
// -------------------------------------------- Lifecycle Processing Methods
/**
* @throws AbortProcessingException {@inheritDoc}
* @throws IllegalStateException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (event == null) {
throw new NullPointerException();
}
if (event instanceof BehaviorEvent) {
BehaviorEvent behaviorEvent = (BehaviorEvent) event;
Behavior behavior = behaviorEvent.getBehavior();
behavior.broadcast(behaviorEvent);
}
if (listeners == null) {
return;
}
for (FacesListener listener : listeners.asArray(FacesListener.class)) {
if (event.isAppropriateListener(listener)) {
event.processListener(listener);
}
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void decode(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
String rendererType = getRendererType();
if (rendererType != null) {
Renderer renderer = getRenderer(context);
if (renderer != null) {
renderer.decode(context, this);
} else {
if (LOGGER.isLoggable(FINE)) {
LOGGER.fine("Can't get Renderer for type " + rendererType);
}
}
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void encodeBegin(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
pushComponentToEL(context, null);
if (!isRendered()) {
return;
}
context.getApplication().publishEvent(context, PreRenderComponentEvent.class, this);
String rendererType = getRendererType();
if (rendererType != null) {
Renderer renderer = getRenderer(context);
if (renderer != null) {
renderer.encodeBegin(context, this);
} else {
if (LOGGER.isLoggable(FINE)) {
LOGGER.fine("Can't get Renderer for type " + rendererType);
}
}
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void encodeChildren(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
return;
}
if (getRendererType() != null) {
Renderer renderer = getRenderer(context);
if (renderer != null) {
renderer.encodeChildren(context, this);
}
// We've already logged for this component
} else if (getChildCount() > 0) {
for (UIComponent child : getChildren()) {
child.encodeAll(context);
}
}
}
/**
* @throws IOException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void encodeEnd(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
popComponentFromEL(context);
return;
}
if (getRendererType() != null) {
Renderer renderer = getRenderer(context);
if (renderer != null) {
renderer.encodeEnd(context, this);
}
// We've already logged for this component
}
popComponentFromEL(context);
}
// -------------------------------------------------- Event Listener Methods
/**
*
* Add the specified {@link FacesListener} to the set of listeners registered to receive event
* notifications from this {@link UIComponent}. It is expected that {@link UIComponent} classes
* acting as event sources will have corresponding typesafe APIs for registering listeners of
* the required type, and the implementation of those registration methods will delegate to this
* method. For example:
*
*
* @param listener The {@link FacesListener} to be registered
* @throws NullPointerException if listener is null
*/
@Override
protected void addFacesListener(FacesListener listener) {
if (listener == null) {
throw new NullPointerException();
}
if (listeners == null) {
listeners = new AttachedObjectListHolder<>();
}
listeners.add(listener);
}
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
@Override
protected FacesListener[] getFacesListeners(Class clazz) {
if (clazz == null) {
throw new NullPointerException();
}
if (!FacesListener.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException();
}
if (this.listeners == null) {
return (FacesListener[]) Array.newInstance(clazz, 0);
}
FacesListener[] listeners = this.listeners.asArray(FacesListener.class);
if (listeners.length == 0) {
return (FacesListener[]) Array.newInstance(clazz, 0);
}
List results = new ArrayList<>(listeners.length);
for (FacesListener listener : listeners) {
if (((Class>) clazz).isAssignableFrom(listener.getClass())) {
results.add(listener);
}
}
return results.toArray((FacesListener[]) Array.newInstance(clazz, results.size()));
}
/**
*
* Remove the specified {@link FacesListener} from the set of listeners registered to receive
* event notifications from this {@link UIComponent}.
*
* @param listener The {@link FacesListener} to be deregistered
* @throws NullPointerException if listener is null
*/
@Override
protected void removeFacesListener(FacesListener listener) {
if (listener == null) {
throw new NullPointerException();
}
if (listeners != null) {
listeners.remove(listener);
}
}
/**
* @throws IllegalStateException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void queueEvent(FacesEvent event) {
if (event == null) {
throw new NullPointerException();
}
UIComponent parent = getParent();
if (parent == null) {
throw new IllegalStateException();
}
parent.queueEvent(event);
}
/**
*
* Install the listener instance referenced by argument componentListener as a
* listener for events of type eventClass originating from this specific instance
* of UIComponent. The default implementation creates an inner
* {@link SystemEventListener} instance that wraps argument componentListener as
* the listener argument. This inner class must call through to the argument
* componentListener in its implementation of
* {@link SystemEventListener#processEvent} and its implementation of
* {@link SystemEventListener#isListenerForSource} must return true if the instance class of
* this UIComponent is assignable from the argument to
* isListenerForSource.
*
*
* @param eventClass the Class of event for which listener must be
* fired.
* @param componentListener the implementation of
* {@link javax.faces.event.ComponentSystemEventListener} whose
* {@link javax.faces.event.ComponentSystemEventListener#processEvent} method must be
* called when events of type facesEventClass are fired.
*
* @throws NullPointerException if any of the arguments are null.
*
* @since 2.1
*/
@Override
public void subscribeToEvent(Class extends SystemEvent> eventClass, ComponentSystemEventListener componentListener) {
if (isAnyNull(eventClass, componentListener)) {
throw new NullPointerException();
}
if (initialStateMarked()) {
initialState = false;
}
if (listenersByEventClass == null) {
listenersByEventClass = new HashMap<>(3, 1.0f);
}
SystemEventListener facesLifecycleListener = new ComponentSystemEventListenerAdapter(componentListener, this);
List listenersForEventClass = listenersByEventClass.get(eventClass);
if (listenersForEventClass == null) {
listenersForEventClass = new ArrayList<>(3);
listenersByEventClass.put(eventClass, listenersForEventClass);
}
if (!listenersForEventClass.contains(facesLifecycleListener)) {
listenersForEventClass.add(facesLifecycleListener);
}
}
/**
*
* Remove the listener instance referenced by argument componentListener as a
* listener for events of type eventClass originating from this specific instance
* of UIComponent. When doing the comparison to determine if an existing listener
* is equal to the argument componentListener (and thus must be removed), the
* equals() method on the existing listener must be invoked, passing the
* argument componentListener, rather than the other way around.
*
*
* @param eventClass the Class of event for which listener must be
* removed.
* @param componentListener the implementation of {@link ComponentSystemEventListener} whose
* {@link ComponentSystemEventListener#processEvent} method must no longer be called
* when events of type eventClass are fired.
*
* @throws NullPointerException if any of the arguments are null.
*
* @since 2.1
*/
@Override
public void unsubscribeFromEvent(Class extends SystemEvent> eventClass, ComponentSystemEventListener componentListener) {
if (isAnyNull(eventClass, componentListener)) {
throw new NullPointerException();
}
List listeners = getListenersForEventClass(eventClass);
if (!isEmpty(listeners)) {
for (Iterator i = listeners.iterator(); i.hasNext();) {
ComponentSystemEventListener existingListener = ((ComponentSystemEventListenerAdapter) i.next()).getWrapped();
if (existingListener.equals(componentListener)) {
i.remove();
break;
}
}
}
}
/**
*
* Return the SystemEventListener instances registered on this
* UIComponent instance that are interested in events of type
* eventClass.
*
*
* @param eventClass the Class of event for which the listeners must be returned.
*
* @throws NullPointerException if argument eventClass is null.
*
* @since 2.1
*/
@Override
public List getListenersForEventClass(Class extends SystemEvent> eventClass) {
if (eventClass == null) {
throw new NullPointerException();
}
if (listenersByEventClass != null) {
return listenersByEventClass.get(eventClass);
}
return null;
}
// ------------------------------------------------ Lifecycle Phase Handlers
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void processDecodes(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// Skip processing if our rendered flag is false
if (!isRendered()) {
return;
}
pushComponentToEL(context, null);
try {
// Process all facets and children of this component
Iterator kids = getFacetsAndChildren();
while (kids.hasNext()) {
UIComponent kid = (UIComponent) kids.next();
kid.processDecodes(context);
}
// Process this component itself
try {
decode(context);
} catch (RuntimeException e) {
context.renderResponse();
throw e;
}
} finally {
popComponentFromEL(context);
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void processValidators(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// Skip processing if our rendered flag is false
if (!isRendered()) {
return;
}
pushComponentToEL(context, null);
try {
Application application = context.getApplication();
application.publishEvent(context, PreValidateEvent.class, this);
// Process all the facets and children of this component
Iterator kids = getFacetsAndChildren();
while (kids.hasNext()) {
UIComponent kid = (UIComponent) kids.next();
kid.processValidators(context);
}
application.publishEvent(context, PostValidateEvent.class, this);
} finally {
popComponentFromEL(context);
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public void processUpdates(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// Skip processing if our rendered flag is false
if (!isRendered()) {
return;
}
pushComponentToEL(context, null);
try {
// Process all facets and children of this component
Iterator kids = getFacetsAndChildren();
while (kids.hasNext()) {
UIComponent kid = (UIComponent) kids.next();
kid.processUpdates(context);
}
} finally {
popComponentFromEL(context);
}
}
/**
* @throws NullPointerException {@inheritDoc}
*/
@Override
public Object processSaveState(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if (isTransient()) {
return null;
}
Object[] stateStruct = new Object[2];
Object[] childState = EMPTY_ARRAY;
pushComponentToEL(context, null);
try {
// Process this component itself
stateStruct[MY_STATE] = saveState(context);
// Determine if we have any children to store
int count = getChildCount() + getFacetCount();
if (count > 0) {
// This arraylist will store state
List