// 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.faces.component.UIComponent;
import javax.el.ValueExpression;
import javax.el.MethodExpression;
import javax.faces.context.FacesContext;
$utils.importTagClasses12($component)

// 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
    }

#set ($propertyList = ${component.propertyTagList})
#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

    protected void setProperties(UIComponent component)
    {
        if (!(component instanceof $component.className))
        {
            throw new IllegalArgumentException("Component "+
                component.getClass().getName() +" is no $component.className");
        }
        
        $component.className comp = ($component.className) component;
        
        super.setProperties(component);
        
        FacesContext context = getFacesContext();

#foreach( $property in $propertyList )##            1
#set ($field = $property.fieldName)
#set ($type = $utils.getJspPropertyType12($property))
#if ($property.isLiteralOnly() && $property.className == "boolean")
#set ($type = "String")
#end
#if ($utils.isConverter($property.className))##                   2
        if ($field != null)
        {
            if (!${field}.isLiteralText())
            {
                comp.setValueExpression("$property.name", $field);
            }
            else
            {
                String s = ${field}.getExpressionString();
                if (s != null)
                {            
                    Converter converter = getFacesContext().getApplication().createConverter(s);
                    comp.setConverter(converter);
                }
            }
        }
#elseif ($property.isMethodBinding())##                 2
        if ($field != null)
        {
#if ($property.jspName == "actionListener")
            comp.addActionListener(new MethodExpressionActionListener($field));
#elseif ($property.jspName == "valueChangeListener")
            comp.addValueChangeListener(new MethodExpressionValueChangeListener($field));
#elseif ($property.jspName == "validator")
            comp.addValidator(new MethodExpressionValidator($field));
#elseif ($utils.isStringMethodBindingReturnType($property.methodBindingSignature))##3
            MethodBinding mb;
            if (isValueReference($field))
            {
                mb = context.getApplication().createMethodBinding(
                    $field, $utils.getSignatureParams($property.methodBindingSignature));            
            }
            else
            {
                throw new IllegalStateException("Invalid expression " + $field);
            }
            comp.${utils.getPrefixedPropertyName("set",$property.name)}(mb);
#else##                                                 3
            MethodBinding mb = context.getApplication().createMethodBinding(
                $field, $utils.getSignatureParams($property.methodBindingSignature));
            comp.${utils.getPrefixedPropertyName("set",$property.name)}(mb);
#end##                                                  3
        }
#elseif ($property.isMethodExpression())##            2
        if ($field != null)
        {
#if ($property.jspName == "action")
            comp.setActionExpression($field);
#elseif ($property.jspName == "actionListener")
            comp.addActionListener(new MethodExpressionActionListener($field));
#else
            comp.${utils.getPrefixedPropertyName("set",$property.name)}($field);
#end        
        }        
#else##                                               2
        if ($field != null)
        {
#if ($property.isLiteralOnly())##                         3
#if ($utils.isPrimitiveClass($property.className))##               4
            comp.getAttributes().put("$property.name", ${utils.getBoxedClass($property.className)}.valueOf($field));
#else##                                                   4
            comp.getAttributes().put("$property.name", $field);
#end##                                                    4
#else##                                                 3
            comp.setValueExpression("$property.name", $field);
#end##                                                  3
        } 
#end##                                                2
#end##                                              1
    }

    public void release()
    {
        super.release();
#foreach( $property in $propertyList )
#set ($field = $property.fieldName)
#set ($empty = "null")
        $field = $empty;
#end
    }
}
