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

org.apache.struts.faces.renderer.AbstractRenderer Maven / Gradle / Ivy

There is a newer version: 1.3.8
Show newest version
/*
 * $Id: AbstractRenderer.java 471754 2006-11-06 14:55:09Z husted $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.struts.faces.renderer;


import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.el.ValueBinding;
import javax.faces.render.Renderer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 

Abstract base class for concrete implementations of * javax.faces.render.Renderer for the * Struts-Faces Integration Library.

* * @version $Rev: 471754 $ $Date: 2006-11-06 08:55:09 -0600 (Mon, 06 Nov 2006) $ */ public abstract class AbstractRenderer extends Renderer { // -------------------------------------------------------- Static Variables private static final Log log = LogFactory.getLog(AbstractRenderer.class); // -------------------------------------------------------- Renderer 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() * unless this component has a boolean disabled or * readonly attribute that is set to true.

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null */ public void decode(FacesContext context, UIComponent component) { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } // Disabled or readonly components are not decoded if (isDisabled(component) || isReadOnly(component)) { return; } // Save submitted value on EditableValueHolder components 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 */ public void encodeBegin(FacesContext context, UIComponent component) throws IOException { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } if (log.isTraceEnabled()) { log.trace("encodeBegin(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } // Render the element and attributes for this component 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 */ public void encodeChildren(FacesContext context, UIComponent component) throws IOException { if (context == null || component == null) { throw new NullPointerException(); } if (log.isTraceEnabled()) { log.trace("encodeChildren(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } Iterator kids = component.getChildren().iterator(); while (kids.hasNext()) { UIComponent kid = (UIComponent) kids.next(); kid.encodeBegin(context); if (kid.getRendersChildren()) { kid.encodeChildren(context); } kid.encodeEnd(context); } if (log.isTraceEnabled()) { log.trace("encodeChildren(id=" + component.getId() + ") end"); } } /** *

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 */ public void encodeEnd(FacesContext context, UIComponent component) throws IOException { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } if (log.isTraceEnabled()) { log.trace("encodeEnd(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ")"); } // Render the element closing for this component ResponseWriter writer = context.getResponseWriter(); renderEnd(context, component, writer); } // --------------------------------------------------------- Package Methods // ------------------------------------------------------- Protected Methods /** *

Render nested child components by invoking the encode methods * on those components, but only when the rendered * property is true.

*/ protected void encodeRecursive(FacesContext context, UIComponent component) throws IOException { // suppress rendering if "rendered" property on the component is // false. if (!component.isRendered()) { return; } // Render this component and its children recursively if (log.isTraceEnabled()) { log.trace("encodeRecursive(id=" + component.getId() + ", family=" + component.getFamily() + ", rendererType=" + component.getRendererType() + ") encodeBegin"); } component.encodeBegin(context); if (component.getRendersChildren()) { if (log.isTraceEnabled()) { log.trace("encodeRecursive(id=" + component.getId() + ") delegating"); } component.encodeChildren(context); } else { if (log.isTraceEnabled()) { log.trace("encodeRecursive(id=" + component.getId() + ") recursing"); } Iterator kids = component.getChildren().iterator(); while (kids.hasNext()) { UIComponent kid = (UIComponent) kids.next(); encodeRecursive(context, kid); } } if (log.isTraceEnabled()) { log.trace("encodeRecursive(id=" + component.getId() + ") encodeEnd"); } component.encodeEnd(context); } /** *

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 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 any boolean attributes on the specified list that have * true values on the corresponding attribute of the * specified UIComponent.

* * @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 renderBoolean(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], names[i], names[i]); flag = false; } } } } /** *

Render any attributes on the specified list directly to the * specified ResponseWriter for which the specified * UIComponent has a non-null attribute value. * This method may be used to "pass through" commonly used attribute * name/value pairs with a minimum of code.

* * @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 renderPassThrough(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], value, names[i]); } else { writer.writeAttribute(names[i], value.toString(), names[i]); } } } } /** *

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; } String clientId = component.getClientId(context); Map parameters = context.getExternalContext().getRequestParameterMap(); if (parameters.containsKey(clientId)) { if (log.isTraceEnabled()) { log.trace("setSubmittedValue(" + clientId + "," + (String) parameters.get(clientId)); } component.getAttributes().put("submittedValue", parameters.get(clientId)); } } // --------------------------------------------------------- Private Methods /** *

Decode the current state of the specified UIComponent from the * request contained in the specified FacesContext, and * attempt to convert this state information into an object of the * type equired for this component.

* * @param context FacesContext for the request we are processing * @param component UIComponent to be decoded * * @exception NullPointerException if context or component is null */ /* public void decode(FacesContext context, UIComponent component) { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } // Only input components need to be decoded if (!(component instanceof UIInput)) { return; } UIInput input = (UIInput) component; // Save the old value for use in generating ValueChangedEvents Object oldValue = input.getValue(); if (oldValue instanceof String) { try { oldValue = getAsObject(context, component, (String) oldValue); } catch (ConverterException e) { ; } } input.setPrevious(oldValue); // Decode and convert (if needed) the new value String clientId = component.getClientId(context); Map map = context.getExternalContext().getRequestParameterMap(); String newString = (String) map.get(clientId); Object newValue = null; try { newValue = getAsObject(context, component, newString); input.setValue(newValue); input.setValid(true); } catch (ConverterException e) { input.setValue(newValue); input.setValid(false); addConverterMessage(context, component, e.getMessage()); } } */ // --------------------------------------------------------- Package Methods // ------------------------------------------------------- Protected Methods /** *

Add an error message denoting a conversion failure.

* * @param context The FacesContext for this request * @param component The UIComponent that experienced * the conversion failure * @param text The text of the error message */ /* protected void addConverterMessage(FacesContext context, UIComponent component, String text) { String clientId = component.getClientId(context); FacesMessage message = new FacesMessage (text, "Conversion error on component '" + clientId + "'"); context.addMessage(clientId, message); } */ /** *

Convert the String representation of this component's value * to the corresponding Object representation. The default * implementation utilizes the getAsObject() method of any * associated Converter.

* * @param context The FacesContext for this request * @param component The UIComponent whose value is * being converted * @param value The String representation to be converted * * @exception ConverterException if conversion fails */ /* protected Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException { // Identify any Converter associated with this component value ValueBinding vb = component.getValueBinding("value"); Converter converter = null; if (component instanceof ValueHolder) { // Acquire explicitly assigned Converter (if any) converter = ((ValueHolder) component).getConverter(); } if ((converter == null) && (vb != null)) { Class type = vb.getType(context); if ((type == null) || (type == String.class)) { return (value); // No conversion required for Strings } // Acquire implicit by-type Converter (if any) converter = context.getApplication().createConverter(type); } // Convert the result if we identified a Converter if (converter != null) { return (converter.getAsObject(context, component, value)); } else { return (value); } } */ /** *

Convert the Object representation of this component's value * to the corresponding String representation. The default implementation * utilizes the getAsString() method of any associated * Converter.

* * @param context The FacesContext for this request * @param component The UIComponent whose value is * being converted * @param value The Object representation to be converted * * @exception ConverterException if conversion fails */ protected String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException { // Identify any Converter associated with this component value ValueBinding vb = component.getValueBinding("value"); Converter converter = null; if (component instanceof ValueHolder) { // Acquire explicitly assigned Converter (if any) converter = ((ValueHolder) component).getConverter(); } if ((converter == null) && (vb != null)) { // Acquire implicit by-type Converter (if any) Class type = vb.getType(context); if (type != null) { converter = context.getApplication().createConverter(type); } } // Convert the result if we identified a Converter if (converter != null) { return (converter.getAsString(context, component, value)); } else if (value == null) { return (""); } else if (value instanceof String) { return ((String) value); } else { return (value.toString()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy