// 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)
#end
#end
#if ($addMe)
import javax.el.MethodExpression;
#end
#if ($addMeMb)
import org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding;
#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 ${component.tagSuperclass}
#else
    extends javax.faces.webapp.UIComponentTag
#end
{
    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
    private $type $field;
    
#set ($var = $utils.getVariableFromName($property.name))
    public void $utils.getPrefixedPropertyName("set", $property.jspName)($type $var)
    {
        $field = $var;
    }
#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 ($utils.isConverter($property.className))##                   2
        if ($field != null)
        {
            if (!${field}.isLiteralText())
            {
                bean.setValueExpression(${component.className}.${key}, $field);
            }
            else
            {
                String s = ${field}.getExpressionString();
                if (s != null)
                {            
                    Converter converter = getFacesContext().getApplication().createConverter(s);
                    bean.setProperty(${component.className}.${key}, converter);
                }
            }
        }
#elseif ($property.isMethodExpression())
        bean.setProperty(${component.className}.${key}, $field);
#elseif ($property.isMethodBinding())
        if ($field != null)
            bean.setProperty(${component.className}.${key}, new MethodExpressionMethodBinding($field))
#elseif ($property.isLiteralOnly())
        bean.setProperty(${component.className}.${key}, $field);
#elseif ($type == "String[]")
        setStringArrayProperty(bean, ${component.className}.${key}, $field);
#else
        setProperty(bean, ${component.className}.${key}, $field);
#end
#end
    }
    
    public void release()
    {
        super.release();
#foreach( $property in $propertyList )
#set ($field = $property.fieldName)
#set ($empty = "null")
        $field = $empty;
#end
    }
}
