Package com.caucho.jsp.java

Source Code of com.caucho.jsp.java.JsfTagNode

/*
* Copyright (c) 1998-2010 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
*   Free Software Foundation, Inc.
*   59 Temple Place, Suite 330
*   Boston, MA 02111-1307  USA
*
* @author Scott Ferguson
*/

package com.caucho.jsp.java;

import com.caucho.jsp.*;
import com.caucho.config.*;
import com.caucho.util.*;
import com.caucho.xml.QName;
import com.caucho.vfs.*;

import javax.servlet.jsp.tagext.*;
import javax.faces.component.*;
import javax.faces.event.*;
import javax.el.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.*;

/**
* Represents a custom tag.
*/
public class JsfTagNode extends JsfNode
{
  private JspNode _next;
  private Class _componentClass;

  private String _facetName;

  private Attr _idAttr;
  private String _prevJsfId;

  private Attr _bindingAttr;

  private ArrayList<Attr> _attrList = new ArrayList<Attr>();

  public void setComponentClass(Class cl)
  {
    _componentClass = cl;
  }

  public void setNext(JspNode next)
  {
    _next = next;
  }

  /**
   * Adds an attribute.
   */
  public void addAttribute(QName qName, String value)
    throws JspParseException
  {
    String name = qName.getName();

    String setterName = ("set" + Character.toUpperCase(name.charAt(0))
       + name.substring(1));

    if (name.equals("action")
  && ActionSource2.class.isAssignableFrom(_componentClass))
      setterName = "setActionExpression";
    else if (name.equals("actionListener")
       && ActionSource2.class.isAssignableFrom(_componentClass))
      setterName = "addActionListener";
    else if (name.equals("escape") &&
             UISelectItem.class.isAssignableFrom(_componentClass))
      setterName = "setItemEscaped";

    Method method = findSetter(_componentClass, setterName);

    if (method != null) {
      _attrList.add(new Attr(name, method, value));
    }
    else if (name.equals("binding")) {
      if (! value.startsWith("#{"))
  throw error(L.l("JSF binding attribute requires a deferred value at '{0}'",
      value));
 
      Attr attr = new Attr(name, method, value);

      _bindingAttr = attr;
      _attrList.add(attr);
    }
    else {
      super.addAttribute(qName, value);
    }
  }

  /**
   * Adds a JspAttribute attribute.
   *
   * @param qName the name of the attribute.
   * @param value the value of the attribute.
   */
  public void addAttribute(QName qName, JspAttribute value)
    throws JspParseException
  {
    if (value.isStatic()) {
      addAttribute(qName, value.getStaticText().trim());
    }
    else {
      String name = qName.getName();

      String setterName = ("set" + Character.toUpperCase(name.charAt(0))
         + name.substring(1));

      Method method = findSetter(_componentClass, setterName);

      if (method != null) {
  _attrList.add(new Attr(name, method, value));
      }
      else {
  super.addAttribute(qName, value);
  return;
      }
    }
  }

  /**
   * Called after all the attributes from the tag.
   */
  public void endAttributes()
    throws JspParseException
  {
    if (_parent instanceof JsfFacetNode) {
      _facetName = ((JsfFacetNode) _parent).getName();
    }
    else if (_parent instanceof CustomTag) {
      final QName qName = _parent.getQName();

      if ((qName.getNamespaceURI().indexOf("http://java.sun.com/jsf/core") > -1)
    && "facet".equals(qName.getLocalName())) {

  final Object facetName = ((CustomTag) _parent).getAttribute("name");
 
  if (facetName instanceof String) {
    _facetName = facetName.toString();
  }
      }
    }

    _idAttr = findAttribute("id");

    if (_idAttr != null)
      addJsfId(_parent);
    else if (isJsfIdRequired())
      addJsfId(this);

    if (_idAttr == null) {
      _prevJsfId = getPrevJsfId();
    }
  }

  public void endElement()
  {
    if (isJsfParentRequired()) {
      addJsfId(this);
    }
  }

  String getJsfId()
  {
    if (_idAttr != null)
      return _idAttr.getValue();
    else
      return null;
  }

  private boolean isJsfIdRequired()
  {
    if (EditableValueHolder.class.isAssignableFrom(_componentClass))
      return true;
    else if (ActionSource.class.isAssignableFrom(_componentClass))
      return true;
    else if (ActionSource2.class.isAssignableFrom(_componentClass))
      return true;
    else if (_bindingAttr != null)
      return true;
    else if (UISelectItem.class.isAssignableFrom(_componentClass))
      return true;
    else if (UISelectItems.class.isAssignableFrom(_componentClass))
      return true;
   
    JspNode parent = _parent;

    ArrayList<JspNode> children = parent.getChildren();

    boolean isJsfIdRequired = false;
     
    for (int i = 0; i < children.size(); i++) {
      JspNode child = children.get(i);
 
      if (child == this)
  return isJsfIdRequired;
      else if (child instanceof JsfTagNode) {
  JsfTagNode jsfNode = (JsfTagNode) child;
  String id = jsfNode.getJsfId();

  if (id != null)
    isJsfIdRequired = false;
      }
      else if (child.isJsfParentRequired())
  isJsfIdRequired = true;
    }

    return false;
  }
 
  private String getPrevJsfId()
  {
    JspNode parent = _parent;

    ArrayList<JspNode> children = parent.getChildren();

    if (children != null) {
      boolean isFound = false;
     
      for (int i = children.size() - 1; i >= 0; i--) {
  JspNode child = children.get(i);
 
  if (child == this)
    isFound = true;
  else if (isFound && child instanceof JsfTagNode) {
    JsfTagNode jsfNode = (JsfTagNode) child;
    String id = jsfNode.getJsfId();

    if (id != null)
      return id;
  }
      }
    }

    return null;
  }

  private static void addJsfId(JspNode node)
  {
    if (node == null)
      return;

    addJsfId(node.getParent());

    if (node instanceof JsfTagNode) {
      JsfTagNode jsfNode = (JsfTagNode) node;

      if (jsfNode._idAttr != null)
  return;
     
      jsfNode._idAttr = jsfNode.findAttribute("id");

      if (jsfNode._idAttr == null) {
  Method method = jsfNode.findSetter(jsfNode._componentClass, "setId");

  if (method == null)
    throw new IllegalStateException(jsfNode._componentClass + " id");
     
  String id = "j_id_" + jsfNode._gen.generateJspId();
 
  jsfNode._idAttr = new Attr("id", method, id);

  jsfNode._attrList.add(jsfNode._idAttr);
      }
    }
  }

  private Attr findAttribute(String name)
  {
    for (int i = 0; i < _attrList.size(); i++) {
      Attr attr = _attrList.get(i);
     
      if (attr.getName().equals(name))
  return attr;
    }

    return null;
  }

  /**
   * Generates the XML text representation for the tag validation.
   *
   * @param os write stream to the generated XML.
   */
  public void printXml(WriteStream os)
    throws IOException
  {
    if (_next != null)
      _next.printXml(os);
  }
 
  /**
   * generates prologue data.
   */
  @Override
  public void generatePrologue(JspJavaWriter out)
    throws Exception
  {
    _var = "_jsp_comp" + _gen.uniqueId();
   
    super.generatePrologue(out);
  }
 
  /**
   * Generates the code for a custom tag.
   *
   * @param out the output writer for the generated java.
   */
  public void generate(JspJavaWriter out)
    throws Exception
  {
    String contextVar = "null";

    if (_gen.isJsfPrologueInit())
      contextVar = "_jsp_faces_context";
   
    String parentVar = _parent.getJsfVar();

    String parentBodyVar = _parent.getJsfBodyVar();

    String prevId;

    String oldParentVar = null;

    String bindingVar = null;

    if (isJsfParentRequired()) {
      oldParentVar = "_jsp_jsf_parent_" + _gen.uniqueId();

      out.println("Object " + oldParentVar
      + " = request.getAttribute(\"caucho.jsf.parent\");");
    }

    if (_prevJsfId != null)
      prevId = "\"" + _prevJsfId + "\"";
    else
      prevId = null;

    if (parentBodyVar != null) {
      out.println("com.caucho.jsp.jsf.JsfTagUtil.addVerbatim("
      + parentVar
      + ", " + prevId
      + ", " + parentBodyVar + ");");
    }

    if (! hasBodyContent()) {
    }
    else if (parentBodyVar != null)
      _bodyVar = parentBodyVar;
    else {
      _bodyVar = "_jsp_body" + _gen.uniqueId();

      out.println("com.caucho.jsp.BodyContentImpl " + _bodyVar
      + " = (com.caucho.jsp.BodyContentImpl) pageContext.pushBody();");
      out.println("out =  " + _bodyVar + ";");
    }

    String className;

    if (_bindingAttr != null)
      className = UIComponent.class.getName();
    else
      className = _componentClass.getName();

    out.println(className + " " + _var + ";");

    if (_bindingAttr != null) {
      bindingVar = ("_caucho_value_expr_" +
        _gen.addValueExpr(_bindingAttr.getValue(),
              UIComponent.class.getName()));
    }

    if (_facetName != null) {
      out.print(_var + " = (" + className + ")");
      out.println(" com.caucho.jsp.jsf.JsfTagUtil.findFacet("
      + contextVar
      + ", request"
      + ", " + parentVar
      + ", \"" + _facetName + "\");");

      out.println("if (" + _var + " == null) {");
      out.pushDepth();
     
      out.print(_var + " = (" + className + ")");
      out.println(" com.caucho.jsp.jsf.JsfTagUtil.addFacet("
      + contextVar
      + ", request"
      + ", " + parentVar
      + ", \"" + _facetName + "\""
      + ", " + bindingVar
      + ", " + _componentClass.getName() + ".class);");
    }
    else if (_idAttr != null) {
      out.print(_var + " = (" + className + ")");
      out.println(" com.caucho.jsp.jsf.JsfTagUtil.findPersistent("
      + contextVar
      + ", request"
      + ", " + parentVar
      + ", \"" + _idAttr.getValue() + "\");");

      out.println("if (" + _var + " == null) {");
      out.pushDepth();
     
      out.print(_var + " = (" + className + ")");
      out.println(" com.caucho.jsp.jsf.JsfTagUtil.addPersistent("
      + contextVar
      + ", request"
      + ", " + parentVar
      + ", " + bindingVar
      + ", " + _componentClass.getName() + ".class);");
    }
    else {
      out.print(_var + " = (" + className + ")");

      out.println(" com.caucho.jsp.jsf.JsfTagUtil.addTransient("
      + contextVar
      + ", request"
      + ", " + parentVar
      + ", " + prevId
      + ", " + _componentClass.getName() + ".class);");
    }

    for (int i = 0; i < _attrList.size(); i++) {
      Attr attr = (Attr) _attrList.get(i);

      Method method = attr.getMethod();
      Class type = null;

      if (method != null)
  type = method.getParameterTypes()[0];
      else if (attr.getName().equals("binding"))
  type = UIComponent.class;
     
      JspAttribute jspAttr = attr.getAttr();
      String value = attr.getValue();

      if (jspAttr != null) {
  generateSetParameter(out, _var, jspAttr, method,
           true, null, false, false, null);
      }
      else if (ActionListener.class.isAssignableFrom(type)) {
  String exprVar = "_caucho_method_expr_" + _gen.addMethodExpr(value, "void foo(javax.faces.event.ActionEvent)");
 
  out.println(_var + ".addActionListener(new javax.faces.event.MethodExpressionActionListener(" + exprVar + "));");
      }
      else if ("validator".equals(attr.getName())
         && UIInput.class.isAssignableFrom(_componentClass)) {
  out.print("((javax.faces.component.UIInput)" + _var + ").addValidator(new javax.faces.validator.MethodExpressionValidator(");

  String signature
    = "void foo(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)";

  String exprVar = "_caucho_method_expr_" +
       _gen.addMethodExpr(value, signature);

  out.println(exprVar + "));");
      }
      else if ("valueChangeListener".equals(attr.getName())
         && UIInput.class.isAssignableFrom(_componentClass)) {
  out.print("((javax.faces.component.UIInput)" + _var + ").addValueChangeListener(new javax.faces.event.MethodExpressionValueChangeListener(");

  String signature = "void foo(javax.faces.event.ValueChangeEvent)";

  String exprVar = "_caucho_method_expr_" +
       _gen.addMethodExpr(value, signature);

  out.println(exprVar + "));");
      }
      else if (_bindingAttr != null && ! "id".equals(attr.getName())
         || (value.indexOf("#{") >= 0
       && ! ValueExpression.class.isAssignableFrom(type)
       && ! MethodExpression.class.isAssignableFrom(type))) {
  // jsf/3153
  out.print(_var + ".setValueExpression(\"" + attr.getName() + "\", ");

  String exprVar = "_caucho_value_expr_" + _gen.addValueExpr(value, type.getName());
 
  out.println(exprVar + ");");
      }
      else {
  out.print(_var + "." + method.getName() + "(");

  out.print(generateParameterValue(type, value, true, null, false));
 
  out.println(");");
      }
    }

    if (_idAttr != null || _facetName != null) {
      if (oldParentVar != null)
  out.println("request.setAttribute(\"caucho.jsf.parent\""
        + ", new com.caucho.jsp.jsf.JsfComponentTag("
        + _var + ", true, " + _bodyVar + "));");
     
      out.popDepth();
      out.println("}");

      if (oldParentVar != null) {
  out.println("else");
  out.println("  request.setAttribute(\"caucho.jsf.parent\""
        + ", new com.caucho.jsp.jsf.JsfComponentTag("
        + _var + ", false, " + _bodyVar + "));");
      }
    }

    generateChildren(out);

    if (oldParentVar != null) {
      out.println("request.setAttribute(\"caucho.jsf.parent\", "
      + oldParentVar + ");");
    }

    if (_bodyVar != null && parentBodyVar == null) {
      out.println("out = pageContext.popBody();");
      out.println("pageContext.releaseBody(" + _bodyVar + ");");
    }
  }
}
TOP

Related Classes of com.caucho.jsp.java.JsfTagNode

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.