// WARNING: This file was automatically generated. Do not edit it directly,
//          or you will lose your changes.

/*
 * 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 ${component.tagPackage};

import javax.el.ValueExpression;
import org.apache.myfaces.trinidad.bean.FacesBean;
##$utils.importTagClasses12($component)
#set ($addMeMb = false)
#set ($addMe = false)
#set ($propertyList = ${component.propertyTagList})
#foreach( $property in $propertyList )
#if ($property.isMethodExpression())
#set ($addMe = true)
#end
#if ($property.isMethodBinding())
#set ($addMeMb = true)
#set ($addMb = true)
#set ($addMe = true)
#end
#if ($property.name == "converter")
import javax.faces.convert.Converter;
#end
#if ($property.name == "textAndAccessKey" || $property.name == "labelAndAccessKey" || $property.name == "valueAndAccessKey")
import org.apache.myfaces.trinidadinternal.taglib.util.VirtualAttributeUtils;
#end
#end
#if ($addMb)
import javax.faces.el.MethodBinding;
#end
#if ($addMe)
import javax.el.MethodExpression;
#end
#if ($addMeMb)
import org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding;
#end
import ${component.className};
#if (${component.tagSuperclass})
import ${component.tagSuperclass};
#end

// Generated from class ${component.sourceClassName}.
//
// WARNING: This file was automatically generated. Do not edit it directly,
//          or you will lose your changes.
public class $utils.getClassFromFullClass($component.tagClass)
#if (${component.tagSuperclass})
    extends $utils.getClassFromFullClass(${component.tagSuperclass})
#else
    extends javax.faces.webapp.UIComponentTag
#end
{

  /**
   * Construct an instance of the $utils.getClassFromFullClass($component.tagClass).
   */
  public $utils.getClassFromFullClass($component.tagClass)()
  {
  }

  public String getComponentType()
  {
#if ($component.type)
    return "$component.type";
#else
    return null;
#end
  }

  public String getRendererType()
  {
#if ($component.rendererType && !($component.rendererType == ""))
    return "$component.rendererType";
#else
    return null;
#end
  }

#foreach( $property in $propertyList )
#set ($field = $property.fieldName)
#set ($type = $utils.getJspPropertyType12($property))
##if ($property.isLiteralOnly() && $property.className == "boolean")
##set ($type = "String")
##end
#if ($property.isMethodBinding())
  private MethodExpression $field;
#set ($var = $utils.getVariableFromName($property.name))
  final public void $utils.getPrefixedPropertyName("set", $property.jspName)(MethodExpression $var)
  {
    $field = $var;
  }

#else
  private $type $field;
#set ($var = $utils.getVariableFromName($property.name))
  final public void $utils.getPrefixedPropertyName("set", $property.jspName)($type $var)
  {
    $field = $var;
  }

#end
#end
  @Override
  protected void setProperties(
    FacesBean bean)
  {
    super.setProperties(bean);
#foreach( $property in $propertyList )
#set ($field = $property.fieldName)
#set ($type = $utils.getClassFromFullClass($property.className))
#set ($key = $utils.getConstantNameFromProperty($property.name , "_KEY"))
#if ($property.name == "textAndAccessKey")
    if (_textAndAccessKey != null)
    {
      if (!_textAndAccessKey.isLiteralText())
      {
        VirtualAttributeUtils.setAccessKeyAttribute(
          bean,
          _textAndAccessKey,
          ${utils.getClassFromFullClass($component.className)}.TEXT_KEY,
          ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
      else
      {
        String s = _textAndAccessKey.getExpressionString();
        if (s != null)
          VirtualAttributeUtils.setAccessKeyAttribute(
            bean,
            s,
            ${utils.getClassFromFullClass($component.className)}.TEXT_KEY,
            ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
    }
#elseif ($property.name == "labelAndAccessKey")
    if (_labelAndAccessKey != null)
    {
      if (!_labelAndAccessKey.isLiteralText())
      {
        VirtualAttributeUtils.setAccessKeyAttribute(
          bean,
          _labelAndAccessKey,
          ${utils.getClassFromFullClass($component.className)}.LABEL_KEY,
          ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
      else
      {
        String s = _labelAndAccessKey.getExpressionString();
        if (s != null)
          VirtualAttributeUtils.setAccessKeyAttribute(
            bean,
            s,
            ${utils.getClassFromFullClass($component.className)}.LABEL_KEY,
            ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
    }
#elseif ($property.name == "valueAndAccessKey")
    if (_valueAndAccessKey != null)
    {
      if (!_valueAndAccessKey.isLiteralText())
      {
        VirtualAttributeUtils.setAccessKeyAttribute(
          bean,
          _valueAndAccessKey,
          ${utils.getClassFromFullClass($component.className)}.VALUE_KEY,
          ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
      else
      {
        String s = _valueAndAccessKey.getExpressionString();
        if (s != null)
          VirtualAttributeUtils.setAccessKeyAttribute(
            bean,
            s,
            ${utils.getClassFromFullClass($component.className)}.VALUE_KEY,
            ${utils.getClassFromFullClass($component.className)}.ACCESS_KEY_KEY);
      }
    }
#elseif ($utils.isConverter($property.className))##                   2
    if ($field != null)
    {
      if (!${field}.isLiteralText())
      {
        bean.setValueExpression($utils.getClassFromFullClass(${component.className}).${key}, $field);
      }
      else
      {
        String s = ${field}.getExpressionString();
        if (s != null)
        {
          Converter converter = getFacesContext().getApplication().
            createConverter(s);
          bean.setProperty($utils.getClassFromFullClass(${component.className}).${key}, converter);
        }
      }
    }
#elseif ($property.isMethodExpression())
    bean.setProperty($utils.getClassFromFullClass(${component.className}).${key}, $field);
#elseif ($property.isMethodBinding())
    if ($field != null)
      bean.setProperty($utils.getClassFromFullClass(${component.className}).${key}, new MethodExpressionMethodBinding($field));
#elseif ($property.isLiteralOnly())
    bean.setProperty($utils.getClassFromFullClass(${component.className}).${key}, $field);
#elseif ($type == "String[]")
    setStringArrayProperty(bean, $utils.getClassFromFullClass(${component.className}).${key}, $field);
#else
    setProperty(bean, $utils.getClassFromFullClass(${component.className}).${key}, $field);
#end
#end
  }

  @Override
  public void release()
  {
    super.release();
#foreach( $property in $propertyList )
#set ($field = $property.fieldName)
#set ($empty = "null")
#if ($property.isLiteralOnly() && $property.className == "boolean")
    $field = false;
#else
    $field = $empty;
#end
#end
  }
}
