jakarta.faces.render.Renderer 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.render;
import java.io.IOException;
import java.util.Iterator;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.convert.ConverterException;
/**
*
* A Renderer converts the internal representation of
* {@link UIComponent}s into the output stream (or writer) associated with the response we are creating for a particular
* request. Each Renderer
knows how to render one or more {@link UIComponent} types (or classes), and
* advertises a set of render-dependent attributes that it recognizes for each supported {@link UIComponent}.
*
*
*
* Families of {@link Renderer}s are packaged as a {@link RenderKit}, and together support the rendering of all of the
* {@link UIComponent}s in a view associated with a {@link FacesContext}. Within the set of {@link Renderer}s for a
* particular {@link RenderKit}, each must be uniquely identified by the rendererType
property.
*
*
*
* Individual {@link Renderer} instances will be instantiated as requested during the rendering process, and will remain
* in existence for the remainder of the lifetime of a web application. Because each instance may be invoked from more
* than one request processing thread simultaneously, they MUST be programmed in a thread-safe manner.
*
*
*
*
*
* If the {@link jakarta.faces.event.ListenerFor} annotation is attached to the class definition of a
* Renderer
, that class must also implement {@link jakarta.faces.event.ComponentSystemEventListener}, and
* the action pertaining to the processing of ResourceDependency
on a Renderer
described in
* {@link jakarta.faces.event.ListenerFor} must be taken.
*
*
*
* If the {@link jakarta.faces.application.ResourceDependency} annotation is attached to the class definition of a
* Renderer
, the action pertaining to the processing of ResourceDependency
on a
* Renderer
described in {@link UIComponent#getChildren} must be taken.
*
*
*
*
*
* The generic parameter T represents the component class.
*
*
* @param The component class.
*/
public abstract class Renderer {
/**
*
* The key in the component passthrough attributes {@code Map} for the localName of the element corresponding to the
* component.
*
*
* @since 2.2
*/
public static final String PASSTHROUGH_RENDERER_LOCALNAME_KEY = "elementName";
// ------------------------------------------------------ Rendering Methods
/**
*
* Decode any new state of the specified {@link UIComponent} from the request contained in the specified
* {@link FacesContext}, and store that state on the {@link UIComponent}.
*
*
*
* During decoding, events may be enqueued for later processing (by event listeners that have registered an interest),
* by calling queueEvent()
on the associated {@link UIComponent}.
*
*
* @param context {@link FacesContext} for the request we are processing
* @param component {@link UIComponent} to be decoded.
*
* @throws NullPointerException if context
or component
is null
*/
public void decode(FacesContext context, T component) {
if (null == context || null == component) {
throw new NullPointerException();
}
}
/**
*
* Render the beginning specified {@link UIComponent} to the output stream or writer associated with the response we are
* creating. If the conversion attempted in a previous call to getConvertedValue()
for this component
* failed, the state information saved during execution of decode()
should be used to reproduce the
* incorrect input.
*
*
* @param context {@link FacesContext} for the request we are processing
* @param component {@link UIComponent} to be rendered
*
* @throws IOException if an input/output error occurs while rendering
* @throws NullPointerException if context
or component
is null
*/
public void encodeBegin(FacesContext context, T component) throws IOException {
if (null == context || null == component) {
throw new NullPointerException();
}
}
/**
*
* Render the child components of this {@link UIComponent}, following the rules described for encodeBegin()
* to acquire the appropriate value to be rendered. This method will only be called if the rendersChildren
* property of this component is true
.
*
*
* @param context {@link FacesContext} for the response we are creating
* @param component {@link UIComponent} whose children are to be rendered
*
* @throws IOException if an input/output error occurs while rendering
* @throws NullPointerException if context
or component
is null
*/
public void encodeChildren(FacesContext context, T component) throws IOException {
if (context == null || component == null) {
throw new NullPointerException();
}
if (component.getChildCount() > 0) {
Iterator kids = component.getChildren().iterator();
while (kids.hasNext()) {
UIComponent kid = kids.next();
kid.encodeAll(context);
}
}
}
/**
*
* Render the ending of the current state of the specified {@link UIComponent}, following the rules described for
* encodeBegin()
to acquire the appropriate value to be rendered.
*
*
* @param context {@link FacesContext} for the response we are creating
* @param component {@link UIComponent} to be rendered
*
* @throws IOException if an input/output error occurs while rendering
* @throws NullPointerException if context
or component
is null
*/
public void encodeEnd(FacesContext context, T component) throws IOException {
if (null == context || null == component) {
throw new NullPointerException();
}
}
/**
*
* Convert the component generated client id to a form suitable for transmission to the client.
*
*
*
* The default implementation returns the argument clientId
unchanged.
*
*
* @param context {@link FacesContext} for the current request
* @param clientId the client identifier to be converted to client a specific format.
*
* @throws NullPointerException if context
or clientId
is null
*
* @return the converted {@code clientId}
*/
public String convertClientId(FacesContext context, String clientId) {
if (context == null || clientId == null) {
throw new NullPointerException();
}
return clientId;
}
/**
*
* Return a flag indicating whether this {@link Renderer} is responsible for rendering the children the component it is
* asked to render. The default implementation returns false
.
*
*
* @return the current value of the flag
*/
public boolean getRendersChildren() {
return false;
}
/**
*
* Attempt to convert previously stored state information into an object of the type required for this component
* (optionally using the registered {@link jakarta.faces.convert.Converter} for this component, if there is one). If
* conversion is successful, the new value should be returned from this method; if not, a {@link ConverterException}
* should be thrown.
*
*
* @param context {@link FacesContext} for the request we are processing
* @param component {@link UIComponent} to be decoded.
* @param submittedValue a value stored on the component during decode
.
*
* @throws ConverterException if the submitted value cannot be converted successfully.
* @throws NullPointerException if context
or component
is null
*
* @return the converted value
*/
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
if (context == null || component == null) {
throw new NullPointerException();
}
return submittedValue;
}
}