All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.renderkit.html.AbstractRenderer Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at
 * https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
 */
/*
 * $Id: AbstractRenderer.java,v 1.1.12.1 2009-12-29 04:52:46 jyeary Exp $
 */
package com.sun.webui.jsf.renderkit.html;

import com.sun.webui.jsf.model.Markup;
import com.sun.webui.jsf.util.RenderingUtilities;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import javax.faces.application.Application;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.el.ValueExpression;
import javax.faces.render.Renderer;

/**
 * 

Abstract base class for concrete implementations of * javax.faces.render.Renderer for JavaServer Faces * component libraries.

*/ public abstract class AbstractRenderer extends Renderer { // ------------------------------------------------------ Manifest Constants /** *

Base naem of the resource bundle we will use for localization.

*/ protected static final String BUNDLE = "com.sun.webui.jsf.renderkit.html.Bundle"; // NOI18N /** *

The list of attribute names in the HTML 4.01 Specification that * correspond to the entity type %events;.

*/ public static final String EVENTS_ATTRIBUTES[] = {"onClick", "onDblClick", "onChange", // NOI18N "onMouseDown", "onMouseUp", "onMouseOver", "onMouseMove", "onMouseOut", // NOI18N "onKeyPress", "onKeyDown", "onKeyUp", // NOI18N }; /** *

The list of attribute names in the HTML 4.01 Specification that * correspond to the entity type %i18n;.

*/ public static final String I18N_ATTRIBUTES[] = {"dir", "lang",}; // NOI18N // -------------------------------------------------------- Static Variables // ---------------------------------------------------------- Public Methods /** *

Decode any new state of the specified UIComponent * from the request contained in the specified FacesContext, * and store that state on the UIComponent.

* *

The default implementation calls setSubmittedValue() * on components that implement EditableValueHolder (i.e. input fields)

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null */ @Override public void decode(FacesContext context, UIComponent component) { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } // Save submitted value on EditableValueHolder components // unless they are disabled or read only if (component instanceof EditableValueHolder) { setSubmittedValue(context, component); } } /** *

Render the beginning of the specified UIComponent * to the output stream or writer associated with the response we are * creating.

* *

The default implementation calls renderStart() and * renderAttributes().

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null * * @exception IOException if an input/output error occurs */ @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } /* if (LogUtil.finestEnabled()) { LogUtil.finest("encodeBegin(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } */ // Render the element and attributes for this component if (component.isRendered()) { ResponseWriter writer = context.getResponseWriter(); renderStart(context, component, writer); renderAttributes(context, component, writer); } } /** *

Render the children of the specified UIComponent * to the output stream or writer associated with the response we are * creating.

* *

The default implementation iterates through the children of * this component and renders them.

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null * * @exception IOException if an input/output error occurs */ // We shouldn't bother with a default implementation - this is exactly // what happens when you rendersChildren = false. Why duplicate the // code here? @Override public void encodeChildren(FacesContext context, UIComponent component) throws IOException { // Enforce NPE requirements in the Javadocs if (context == null || component == null) { throw new NullPointerException(); } /* if (LogUtil.finestEnabled()) { LogUtil.finest("encodeChildren(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } */ if (component.isRendered()) { Iterator kids = component.getChildren().iterator(); while (kids.hasNext()) { UIComponent kid = (UIComponent) kids.next(); RenderingUtilities.renderComponent(kid, context); } } } /** *

Render the ending of the specified UIComponent * to the output stream or writer associated with the response we are * creating.

* *

The default implementation calls renderEnd().

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null * * @exception IOException if an input/output error occurs */ @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } /* if (LogUtil.finestEnabled()) { LogUtil.finest("encodeEnd(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } */ // Render the element closing for this component if (component.isRendered()) { ResponseWriter writer = context.getResponseWriter(); renderEnd(context, component, writer); } } // --------------------------------------------------------- Package Methods // ------------------------------------------------------- Protected Methods /** *

Render any boolean attributes on the specified list that have * true values on the corresponding attribute of the * specified UIComponent. Attribute names are * converted to lower case in the rendered output.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * @param names List of attribute names to be passed through * * @exception IOException if an input/output error occurs */ protected void addBooleanAttributes(FacesContext context, UIComponent component, ResponseWriter writer, String names[]) throws IOException { if (names == null) { return; } Map attributes = component.getAttributes(); boolean flag; Object value; for (int i = 0; i < names.length; i++) { value = attributes.get(names[i]); if (value != null) { if (value instanceof String) { flag = Boolean.valueOf((String) value).booleanValue(); } else { flag = Boolean.valueOf(value.toString()).booleanValue(); } if (flag) { writer.writeAttribute(names[i].toLowerCase(), names[i].toLowerCase(), names[i]); flag = false; } } } } // Core attributes that are simple pass throughs private static final String coreAttributes[] = {"style", "title"}; /** *

Render the "core" set of attributes for this UIComponent. * The default implementation conditionally generates the following * attributes with values as specified.

*
    *
  • id - If this component has a non-null * id property, and the identifier does not start with * UIViewRoot.UNIQUE_ID_PREFIX, render the * clientId.
  • *
  • class - If this component has a * non-null styleClass attribute, render its * value, combined with the syles parameter (if any).
  • *
  • style - If this component has a * non-null style attribute, render its * value.
  • *
  • title - If this component has a * non-null title attribute, render its * value.
  • *
* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * @param styles Space-separated list of CSS style classes to add * to the class attribute, or null for none * * @exception IOException if an input/output error occurs */ protected void addCoreAttributes(FacesContext context, UIComponent component, ResponseWriter writer, String styles) throws IOException { String id = component.getId(); writer.writeAttribute("id", component.getClientId(context), "id"); RenderingUtilities.renderStyleClass(context, writer, component, styles); addStringAttributes(context, component, writer, coreAttributes); } /** *

Render any Integer attributes on the specified list that do not have * Integer.MIN_VALUE values on the corresponding attribute of the * specified UIComponent. Attribute names are converted to * lower case in the rendered output.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * @param names List of attribute names to be passed through * * @exception IOException if an input/output error occurs */ protected void addIntegerAttributes(FacesContext context, UIComponent component, ResponseWriter writer, String names[]) throws IOException { if (names == null) { return; } Map attributes = component.getAttributes(); boolean flag; Object value; for (int i = 0; i < names.length; i++) { value = attributes.get(names[i]); if ((value != null) && (value instanceof Integer)) { Integer ivalue = (Integer) value; if (!(ivalue.intValue() == Integer.MIN_VALUE)) { writer.writeAttribute(names[i].toLowerCase(), ivalue, names[i]); } } } } /** *

Add any attributes on the specified list directly to the * specified ResponseWriter for which the specified * UIComponent has a non-null String value. * This method may be used to "pass through" commonly used attribute * name/value pairs with a minimum of code. Attribute names are * converted to lower case in the rendered output.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * @param names List of attribute names to be passed through * * @exception IOException if an input/output error occurs */ protected static void addStringAttributes(FacesContext context, UIComponent component, ResponseWriter writer, String names[]) throws IOException { if (names == null) { return; } Map attributes = component.getAttributes(); Object value; for (int i = 0; i < names.length; i++) { value = attributes.get(names[i]); if (value != null) { if (value instanceof String) { writer.writeAttribute(names[i].toLowerCase(), (String) value, names[i]); } else { writer.writeAttribute(names[i].toLowerCase(), value.toString(), names[i]); } } } } /** *

Return the Application instance for this * web application.

*/ protected Application getApplication() { return getFacesContext().getApplication(); } /** *

Return the value to be stored, as an Object that has been * converted from the String representation (if necessary), or * null if the String representation is null.

* * @param context FacesContext for the current request * @param component Component whose value is being processed * (must be a component that implements ValueHolder * @param value String representation of the value */ protected Object getAsObject(FacesContext context, UIComponent component, String value) { if (value == null) { return null; } Converter converter = ((ValueHolder) component).getConverter(); if (converter == null) { ValueExpression vb = component.getValueExpression("value"); if (vb != null) { Class clazz = vb.getType(context.getELContext()); if (clazz != null) { converter = getApplication().createConverter(clazz); } } } if (converter != null) { return converter.getAsObject(context, component, value); } else { return value; } } /** *

Return the value to be rendered, as a String (converted * if necessary), or null if the value is null.

* * @param context FacesContext for the current request * @param component Component whose value is to be retrieved (must be * a component that implements ValueHolder) */ protected String getAsString(FacesContext context, UIComponent component) { if (component instanceof EditableValueHolder) { Object submittedValue = ((EditableValueHolder) component).getSubmittedValue(); if (submittedValue != null) { return (String) submittedValue; } } Object value = ((ValueHolder) component).getValue(); if (value == null) { return null; } Converter converter = ((ValueHolder) component).getConverter(); if (converter == null) { if (value instanceof String) { return (String) value; } converter = getApplication().createConverter(value.getClass()); } if (converter != null) { return converter.getAsString(context, component, value); } else { return value.toString(); } } /** *

Return the ExternalContext instance for the current * request.

*/ protected ExternalContext getExternalContext() { return (FacesContext.getCurrentInstance().getExternalContext()); } /** *

Return the FacesContext instance for the current * request.

*/ protected FacesContext getFacesContext() { return (FacesContext.getCurrentInstance()); } /** *

Retrieve the submitted value from the request parameters for * this request. The default implementation retrieves the parameter * value that corresponds to the client identifier of this component.

* * @param context FacesContext for the current request * @param component UIComponent whose * submitted value is to be retrieved */ protected Object getSubmittedValue(FacesContext context, UIComponent component) { String clientId = component.getClientId(context); Map parameters = context.getExternalContext().getRequestParameterMap(); return parameters.get(clientId); } /** *

Return true if the specified component is disabled.

* * @param component UIComponent to be checked */ protected boolean isDisabled(UIComponent component) { Object disabled = component.getAttributes().get("disabled"); if (disabled == null) { return (false); } if (disabled instanceof String) { return (Boolean.valueOf((String) disabled).booleanValue()); } else { return (disabled.equals(Boolean.TRUE)); } } /** *

Return true if we are we running in a portlet * environment, as opposed to a servlet based web application.

* * @param context FacesContext for the current request */ protected boolean isPortlet(FacesContext context) { return false; // TODO - implement a dynamic check } /** *

Return true if the specified component is read only.

* * @param component UIComponent to be checked */ protected boolean isReadOnly(UIComponent component) { Object readonly = component.getAttributes().get("readonly"); if (readonly == null) { return (false); } if (readonly instanceof String) { return (Boolean.valueOf((String) readonly).booleanValue()); } else { return (readonly.equals(Boolean.TRUE)); } } /** *

Render the element attributes for the generated markup related to this * component. Simple renderers that create a single markup element * for this component should override this method and include calls to * to writeAttribute() and writeURIAttribute * on the specified ResponseWriter.

* *

The default implementation does nothing.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * * @exception IOException if an input/output error occurs */ protected void renderAttributes(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { } /** *

Render the element end for the generated markup related to this * component. Simple renderers that create a single markup element * for this component should override this method and include a call * to endElement() on the specified * ResponseWriter.

* *

The default implementation does nothing.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * * @exception IOException if an input/output error occurs */ protected void renderEnd(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { } /** *

Render the specified markup to the current response.

* * @param context FacesContext for the current request * @param component UIComponent associated with this markup * @param writer ResponseWriter to which the markup * should be rendered * @param markup {@link Markup} to be rendered */ protected void renderMarkup(FacesContext context, UIComponent component, ResponseWriter writer, Markup markup) throws IOException { writer.write(markup.getMarkup()); } /** *

Render the element start for the generated markup related to this * component. Simple renderers that create a single markup element * for this component should override this method and include a call * to startElement() on the specified * ResponseWriter.

* *

The default implementation does nothing.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored * @param writer ResponseWriter to which the element * start should be rendered * * @exception IOException if an input/output error occurs */ protected void renderStart(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { } /** *

If a submitted value was included on this request, store it in the * component as appropriate.

* *

The default implementation determines whether this component * implements EditableValueHolder. If so, it checks for a * request parameter with the same name as the clientId * of this UIComponent. If there is such a parameter, its * value is passed (as a String) to the setSubmittedValue() * method on the EditableValueHolder component.

* * @param context FacesContext for the current request * @param component EditableValueHolder component whose * submitted value is to be stored */ protected void setSubmittedValue(FacesContext context, UIComponent component) { if (!(component instanceof EditableValueHolder)) { return; } component.getAttributes().put("submittedValue", // NOI18N getSubmittedValue(context, component)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy