package ${packageName};
#*
 * $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.
 *#
import java.io.IOException;
import java.util.Map;

#if(${clazz.hasBody()})
import org.apache.tiles.autotag.core.runtime.ModelBody;
#end
import org.apache.tiles.autotag.freemarker.runtime.Body#if(!${clazz.hasBody()})less#{end}FMModel;
import org.apache.tiles.autotag.freemarker.runtime.FreemarkerUtil;
import org.apache.tiles.request.Request;

import freemarker.template.TemplateModel;

/**
#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
 * ${line}
#end
 */
public class ${clazz.tagClassPrefix}FMModel extends Body#if(!${clazz.hasBody()})less#{end}FMModel {

    /**
     * The template model.
     */
    private ${clazz.name} model;

    /**
     * Constructor.
     *
     * @param model
     *            The template model.
     */
    public ${clazz.tagClassPrefix}FMModel(${clazz.name} model) {
        this.model = model;
    }

    /** {@inheritDoc} */
    @Override
    public void execute(Map<String, TemplateModel> parms, Request request#if(${clazz.hasBody()}), ModelBody modelBody#end) throws IOException {
        model.execute(
#foreach($parameter in ${clazz.parameters})
            ($stringTool.getClassToCast(${parameter.type})) FreemarkerUtil.getAsObject(parms.get("${parameter.exportedName}"), $stringTool.getDefaultValue(${parameter.type}, ${parameter.defaultValue})),
#end
                request#if(${clazz.hasBody()}), modelBody#end

        );
    }
}
