Package org.xulfaces.renderer

Source Code of org.xulfaces.renderer.XULRenderer

/*
*   xulfaces : bring XUL power to Java
*  
*  Copyright (C) 2005  Olivier SCHMITT
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package org.xulfaces.renderer;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.FacesException;
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.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.ActionEvent;
import javax.faces.render.Renderer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xulfaces.MultiActionSource;
import org.xulfaces.SmoothlyUpdateable;
import org.xulfaces.annotation.faces.ATTRIBUTE;
import org.xulfaces.annotation.faces.COMPONENT;
import org.xulfaces.annotation.faces.RENDERER;
import org.xulfaces.bridge.Bridge;
import org.xulfaces.bridge.Zone;
import org.xulfaces.bridge.command.UpdateZoneCommand;
import org.xulfaces.utils.XulUtils;


/**
*
* @author kito31
* @version $Id: XULRenderer.java,v 1.34 2007/06/10 19:47:06 kito31 Exp $
*/
@RENDERER(family = "xul.component.family", type = "xul.renderer.Abstract", kit = "XUL_RENDERKIT")
public abstract class XULRenderer extends Renderer {

  private static final Log log = LogFactory.getLog(XULRenderer.class);
 
  protected static final String METHOD_BINDED_PREFIX = "XF_MB_";
 

  protected boolean isSubmitted(FacesContext facesContext, UIComponent uiComponent) {
    String clientId = uiComponent.getClientId(facesContext);
    Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
    boolean found = paramMap.containsKey(clientId);
    if(log.isDebugEnabled()){
      if(found){
        log.debug(uiComponent.getClass().getName() + " " + uiComponent.getId() + " found in request")
      }     
    }
    return found;
  }
   
 
  /**
   * <p></p>
   * @param facesContext
   * @param uiComponent
   * @return <code>true</code> if a method
   */
  protected boolean isMethodBindedSubmitted(FacesContext facesContext, UIComponent uiComponent) {
    String clientId = METHOD_BINDED_PREFIX + uiComponent.getClientId(facesContext) ;
    Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
    boolean found = paramMap.containsKey(clientId);
    if(log.isDebugEnabled()){
      if(found){
        log.debug("Method binded for " + clientId + " found in request.")
      }     
    }
    return found;
  }
 
 
 
  protected Object isSubmitted(FacesContext facesContext, String clientId) {
    Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
    return paramMap.get(clientId);
  }

  public static void renderChild(FacesContext context, UIComponent child) throws IOException {

    if (!child.isRendered()) {
      return;
    }

    child.encodeBegin(context);
    if (child.getRendersChildren()) {
      child.encodeChildren(context);
    } else {
      renderChildren(context, child);
    }
    child.encodeEnd(context);
  }

  public static void renderChildren(FacesContext facesContext, UIComponent component) throws IOException {
    if (component.getChildCount() > 0) {
      for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
        UIComponent child = (UIComponent) it.next();
        renderChild(facesContext, child);
      }
    }
  }

  public Object getProperty(FacesContext context, String name, UIComponent component) {
    Object result = null;
    ValueBinding valueBinding = component.getValueBinding(name);
    if (valueBinding != null) {
      result = valueBinding.getValue(context);
    } else {
      result = component.getAttributes().get(name);
    }
    return result;
  }

  public String convertAsString(FacesContext context, UIComponent component, Object value) {
    if (value != null) {
      if (value instanceof String) {
        return value.toString();
      }
      try {
        Converter converter = context.getApplication().createConverter(value.getClass());
        if (converter != null) {
          return converter.getAsString(context, component, value);
        }

      } catch (FacesException e) {
        return value.toString();
      }
      try {
        return value.toString();
      } catch (Exception e) {
      }
    }
    return "";
  }

  protected void renderAttribute(FacesContext facesContext, UIComponent component, String name) throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();
    Object object = component.getAttributes().get(name);
    if (object != null) {
      responseWriter.writeAttribute(name, "" + object, name);
    }
  }
 
  /**
   * <p>Render component attributes using ATTRIBUTE annotations.</p>
  
   * @param facesContext The FacesContext
   * @param component The component to render
   * @param annotatedAttributes List of array {Field,ATTRIBUTE}
   * @throws IOException
   */
  protected void renderAttributes(FacesContext facesContext, UIComponent component, List annotatedAttributes)
  throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();
    Iterator iterator = annotatedAttributes.iterator();
    while(iterator.hasNext()){
     
      Object[] annotatedAttribute = (Object[]) iterator.next();
     
      Field field = (Field) annotatedAttribute[0];
      String name = field.getName();
      ATTRIBUTE attribute = (ATTRIBUTE) annotatedAttribute[1];
      if(attribute.automateRendering()){
        if(attribute.supportsMethodBinding()){
          renderBindedMethod(facesContext, component,name);
        }
        else {
          Object attributeValue = component.getAttributes().get(name);
          if (attributeValue != null) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(attributeValue);
            if (log.isDebugEnabled()) {
              log.debug("Component " + component.getClass().getName()
                  + " "
                  + component.getId()
                  + " attribute "
                  + name
                  + "="
                  + stringBuffer.toString());
            }
            responseWriter.writeAttribute(name, stringBuffer.toString(), name);
         
        }       
      }       
    }   
  }

  /**
   * <p>Render a binded method associated to multi action source component.</p>
   *
   * @param facesContext The faces context
   * @param component The component
   * @param attributeName The attribute name which is method binded
   * @throws IOException An IOException if writing turns bad.
   */
  protected void renderBindedMethod(FacesContext facesContext, UIComponent component, String attributeName) throws IOException {
    if(!(component instanceof MultiActionSource)){
      throw new IllegalArgumentException("component arg is not MultiActionSource");
    }
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    StringBuffer stringBuffer = new StringBuffer();
    MultiActionSource xulComponent = (MultiActionSource) component;
    MethodBinding methodBinding = xulComponent.getMethodBinding(attributeName);
    if(methodBinding != null){
      stringBuffer.append("triggerBindedMethod('");
      stringBuffer.append(component.getClientId(facesContext));
      stringBuffer.append("','");
      stringBuffer.append(attributeName);
      stringBuffer.append("');");           
      responseWriter.writeAttribute(attributeName, stringBuffer.toString(), attributeName);           
    }
    else {
      // Probably a javascript event handler ...
      Object value = component.getAttributes().get(attributeName);
      if(value != null){
        stringBuffer.append(value);
        responseWriter.writeAttribute(attributeName, stringBuffer.toString(), attributeName);
      }
    }
  }
 
 
 
  @Override
  public void decode(FacesContext facesContext, UIComponent component) {
    super.decode(facesContext, component);
    if(isMethodBindedSubmitted(facesContext, component)){
      Map params = facesContext.getExternalContext().getRequestParameterMap();
      String value = (String) params.get(METHOD_BINDED_PREFIX+component.getClientId(facesContext));
      if(component instanceof MultiActionSource){
        MultiActionSource multiActionSource = (MultiActionSource) component;
        MethodBinding methodBinding = multiActionSource.getMethodBinding(value);
        multiActionSource.setAction(methodBinding);
        if(methodBinding != null){
          component.queueEvent(new ActionEvent(component));
        }
      }
    }
  }

  @Override
  public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {

    super.encodeBegin(facesContext, component);
    processSmoothlyUpdateable(facesContext,component);
  }
 
  protected String buildTargetName(UIComponent component){
    StringBuffer stringBuffer = new StringBuffer(component.getClass().getName());
    stringBuffer.append(" ");
    stringBuffer.append(component.getId());
    return stringBuffer.toString();
  }
 
 
  protected void processSmoothlyUpdateable(FacesContext facesContext,UIComponent component){
    // If parent component is smoothly updateable, it has no sense to add the current child to
    // the bridge for client side update. The parent will be updated and then all its children.
    if(!isParentSmoothlyUpdateable(component)){   
      if (component instanceof SmoothlyUpdateable) {
        SmoothlyUpdateable smoothlyUpdateable = (SmoothlyUpdateable) component;
        if (smoothlyUpdateable.needsUpdate()) {
          Bridge bridge = XulUtils.getBridge();
          Zone zone = new Zone(component.getClientId(facesContext));
          if (log.isDebugEnabled()) {
            log.debug("Add UpdateZoneCommand for DOM zone " + zone.getNodeId());
          }
         
          bridge.addCommand(new UpdateZoneCommand(zone,buildTargetName(component)));
        }
      }
    }
  }
 
  protected boolean isParentSmoothlyUpdateable(UIComponent component){
    boolean smoothlyUpdateable = false;   
    UIComponent parent = component.getParent();
    Boolean parentUpdateSmoothly = (Boolean) parent.getAttributes().get("updateSmoothly");   
    if(parentUpdateSmoothly!=null){
      return parentUpdateSmoothly.booleanValue();         
    }   
    return smoothlyUpdateable;
  }

  protected void renderDisabledAttribute(FacesContext facesContext,UIComponent component) throws IOException{
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    Boolean disabled = (Boolean) component.getAttributes().get("disabled");
    if (disabled != null) {
      if (disabled.booleanValue()) {
        if (log.isDebugEnabled()) {
          log.debug("Component " + component.getClass().getName() + " " + component.getId() + " attribute disabled=" + disabled);
        }
        responseWriter.writeAttribute("disabled", disabled.toString(), "disabled");
      }
    }
  }
 
  /**
     * Renderers override this method in case output value needs to be
     * formatted
     */
    protected String getFormattedValue(FacesContext context, UIComponent component,
                                       Object currentValue)
        throws ConverterException {

        String result = null;
        // formatting is supported only for components that support
        // converting value attributes.
        if (!(component instanceof ValueHolder)) {
            if (currentValue != null) {
                result = currentValue.toString();
            }
            return result;
        }

        Converter converter = null;

        // If there is a converter attribute, use it to to ask application
        // instance for a converter with this identifer.

        if (component instanceof ValueHolder) {
            converter = ((ValueHolder) component).getConverter();
        }

        // if value is null and no converter attribute is specified, then
        // return a zero length String.
        if (converter == null && currentValue == null) {
            return "";
        }

        if (converter == null) {
            // Do not look for "by-type" converters for Strings
            if (currentValue instanceof String) {
                return (String) currentValue;
            }

            // if converter attribute set, try to acquire a converter
            // using its class type.

            Class converterType = currentValue.getClass();
            converter = null;//Util.getConverterForClass(converterType);

            // if there is no default converter available for this identifier,
            // assume the model type to be String.
            if (converter == null && currentValue != null) {
                result = currentValue.toString();
                return result;
            }
        }

        if (converter != null) {
            result = converter.getAsString(context, component, currentValue);

            return result;
        } else {
            // throw converter exception if no converter can be
            // identified        
            throw new ConverterException("Converter error.");
        }
    }
   
    public boolean isMethodReference(String ref){
     
      if (ref != null) {
        if ((ref.indexOf("#{") != -1) &&
          (ref.indexOf("#{") < ref.indexOf('}'))) {
          return true;
        }
      }
        return false;         
    }
}
TOP

Related Classes of org.xulfaces.renderer.XULRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.