#*
 * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
 *
 * 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.
 *#/*
 * This file was automatically generated by Apache Tiles Autotag.
 */
package ${packageName};

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

#if(${clazz.hasBody()})
import org.apache.tiles.autotag.core.runtime.ModelBody;
#end
import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
import org.apache.tiles.request.Request;

/**
#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
 * ${line}
#end
 */
public class ${clazz.tagClassPrefix}Tag extends SimpleTagSupport {

    /**
     * The template model.
     */
    private ${clazz.name} model = new ${clazz.name}();

#foreach($parameter in ${clazz.parameters})
    /**
#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
     * ${line}
#end
     */
    private ${parameter.type} ${parameter.name};

#end
#foreach($parameter in ${clazz.parameters})
    /**
     * Getter for ${parameter.exportedName} property.
     *
     * @return
#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
     * ${line}
#end
     */
    public ${parameter.type} #if(${parameter.type} == 'boolean')is#{else}get#end${parameter.getterSetterSuffix}() {
        return ${parameter.name};
    }

    /**
     * Setter for ${parameter.exportedName} property.
     *
     * @param ${parameter.name}
#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
     * ${line}
#end
     */
    public void set${parameter.getterSetterSuffix}(${parameter.type} ${parameter.name}) {
        this.${parameter.name} = ${parameter.name};
    }

#end
    /** {@inheritDoc} */
    @Override
    public void doTag() throws JspException, IOException {
        AutotagRuntime runtime = new ${runtimeClass}();
        if (runtime instanceof SimpleTagSupport) {
            SimpleTagSupport tag = (SimpleTagSupport) runtime;
            tag.setJspContext(getJspContext());
            tag.setJspBody(getJspBody());
            tag.setParent(getParent());
            tag.doTag();
        }
        Request request = runtime.createRequest();        
#if(${clazz.hasBody()})
        ModelBody modelBody = runtime.createModelBody();
#end
        model.execute(
#foreach($parameter in ${clazz.parameters})
            ${parameter.name},
#end
            request#if(${clazz.hasBody()}), modelBody#end

        );
    }
}
