/*
 * Copyright 2002-2005 the original author or authors.
 * 
 * Licensed 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 org.springframework.web.servlet.view.velocity;

import org.springframework.web.servlet.view.AbstractUrlBasedView;

/**
 * Convenience subclass of UrlBasedViewResolver that supports VelocityLayoutView
 * (i.e. Velocity templates w/ layout support) and custom subclasses of it.
 *
 * <p>The view class for all views generated by this resolver can be specified
 * via setViewClass. See UrlBasedViewResolver's javadocs for details.
 *
 * <p>Note: When chaining ViewResolvers, a VelocityToolboxViewResolver always needs
 * to be last, as it will attempt to resolve any view name, no matter whether
 * the underlying resource actually exists.
 *
 * @author Shinbou Kawai
 * @since 12.05.2005
 * @see #setViewClass
 * @see #setPrefix
 * @see #setSuffix
 * @see #setRequestContextAttribute
 * @see #setExposeSpringMacroHelpers
 * @see #setVelocityFormatterAttribute
 * @see #setDateToolAttribute
 * @see #setNumberToolAttribute
 * @see VelocityLayoutView
 */
public class VelocityLayoutViewResolver extends VelocityToolboxViewResolver {

    private String layoutUrl = null;
    private String layoutKey = null;
    private String screenContentKey = null;

    /**
     * Sets default viewClass to VelocityLayoutView.
     * @see #setViewClass
     */
    public VelocityLayoutViewResolver() {
        this.setViewClass(VelocityLayoutView.class);
    }

    /**
     * Set the layout template to use. Default is "layout.vm".
     * @param layoutUrl the template location (relative to the template
     * root directory)
     */
    public void setLayoutUrl(String layoutUrl) {
        this.layoutUrl = layoutUrl;
    }

    /**
     * Set the context key used to specify an alternate layout to be used instead
     * of the default layout. Screen content templates can override the layout
     * template that they wish to be wrapped with by setting this value in the
     * template, for example:<br>
     * <code>#set( $layout = "MyLayout.vm" )</code>
     * <p>The default key is "layout", as illustrated above.
     * @param layoutKey the name of the key you wish to use in your
     * screen content templates to override the layout template
     */
    public void setLayoutKey(String layoutKey) {
        this.layoutKey = layoutKey;
    }

    /**
     * Set the name of the context key that will hold the content of
     * the screen within the layout template. This key must be present
     * in the layout template for the current screen to be rendered.
     * <p>Default is "screen_content": accessed in VTL as
     * <code>$screen_content</code>.
     * @param screenContentKey the name of the screen content key to use
     */
    public void setScreenContentKey(String screenContentKey) {
        this.screenContentKey = screenContentKey;
    }

	protected AbstractUrlBasedView buildView(String viewName) throws Exception {
		VelocityView view = (VelocityView) super.buildView(viewName);
        if (this.layoutUrl != null) {
            ((VelocityLayoutView) view).setLayoutUrl(this.layoutUrl);
        }
        if (this.layoutKey != null) {
            ((VelocityLayoutView) view).setLayoutKey(this.layoutKey);
        }
        if (this.screenContentKey != null) {
            ((VelocityLayoutView) view).setScreenContentKey(this.screenContentKey);
        }
        return view;
    }

}
