001package org.apache.turbine.modules.layouts;
002
003
004import javax.servlet.http.HttpServletResponse;
005
006import org.apache.logging.log4j.LogManager;
007
008/*
009 * Licensed to the Apache Software Foundation (ASF) under one
010 * or more contributor license agreements.  See the NOTICE file
011 * distributed with this work for additional information
012 * regarding copyright ownership.  The ASF licenses this file
013 * to you under the Apache License, Version 2.0 (the
014 * "License"); you may not use this file except in compliance
015 * with the License.  You may obtain a copy of the License at
016 *
017 *   http://www.apache.org/licenses/LICENSE-2.0
018 *
019 * Unless required by applicable law or agreed to in writing,
020 * software distributed under the License is distributed on an
021 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
022 * KIND, either express or implied.  See the License for the
023 * specific language governing permissions and limitations
024 * under the License.
025 */
026
027
028import org.apache.logging.log4j.Logger;
029import org.apache.turbine.Turbine;
030import org.apache.turbine.annotation.TurbineService;
031import org.apache.turbine.modules.Layout;
032import org.apache.turbine.pipeline.PipelineData;
033import org.apache.turbine.services.velocity.VelocityService;
034import org.apache.turbine.util.RunData;
035import org.apache.velocity.context.Context;
036
037/**
038 * This Layout module allows Velocity templates
039 * to be used as layouts.
040 *
041 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
042 */
043public abstract class VelocityLayout implements Layout
044{
045    /** Logging */
046    protected final Logger log = LogManager.getLogger(this.getClass());
047
048    /** The prefix for lookup up layout pages */
049    protected static final String prefix = PREFIX + "/";
050
051    /** Injected service instance */
052    @TurbineService
053    protected VelocityService velocityService;
054
055    /**
056     * Method called by LayoutLoader.
057     *
058     *
059     * @param pipelineData PipelineData
060     * @throws Exception generic exception
061     */
062    @Override
063    public void doBuild(PipelineData pipelineData)
064        throws Exception
065    {
066        RunData data = pipelineData.getRunData();
067        // Get the context needed by Velocity.
068        Context context = velocityService.getContext(pipelineData);
069
070        // Provide objects to Velocity context
071        populateContext(pipelineData, context);
072
073        // Grab the layout template set in the VelocityPage.
074        // If null, then use the default layout template
075        // (done by the TemplateInfo object)
076        String templateName = data.getTemplateInfo().getLayoutTemplate();
077
078        // Set the locale and content type
079        data.getResponse().setLocale(data.getLocale());
080        data.getResponse().setContentType(data.getContentType());
081
082        log.debug("Now trying to render layout {}", templateName);
083
084        // Finally, generate the layout template and send it to the browser
085        render(pipelineData, context, templateName);
086    }
087
088    /**
089     * Populate Velocity context
090     *
091     * @param pipelineData PipelineData
092     * @param context the Velocity context
093     *
094     * @throws Exception if evaluation fails
095     */
096    protected abstract void populateContext(PipelineData pipelineData, Context context)
097        throws Exception;
098
099    /**
100     * Render layout
101     *
102     * @param pipelineData PipelineData
103     * @param context the Velocity context
104     * @param templateName relative path to Velocity template
105     *
106     * @throws Exception if rendering fails
107     */
108    protected void render(PipelineData pipelineData, Context context, String templateName)
109        throws Exception
110    {
111        velocityService.handleRequest(context,
112                prefix + templateName,
113                pipelineData.get(Turbine.class, HttpServletResponse.class)
114                    .getOutputStream());
115    }
116}