#literal()
// 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)

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))
 
    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 ($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
            comp.getAttributes().put("$property.name", $field);
#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)
#if($utils.getJspPropertyType12($property) == "boolean")
#set ($empty = "false")
#else
#set ($empty = "null")
#end
        $field = $empty;
#end
    }
}
#end
