    001package org.apache.turbine.modules.screens;
    002
    003/*
    004 * Licensed to the Apache Software Foundation (ASF) under one
    005 * or more contributor license agreements.  See the NOTICE file
    006 * distributed with this work for additional information
    007 * regarding copyright ownership.  The ASF licenses this file
    008 * to you under the Apache License, Version 2.0 (the
    009 * "License"); you may not use this file except in compliance
    010 * with the License.  You may obtain a copy of the License at
    011 *
    012 *   http://www.apache.org/licenses/LICENSE-2.0
    013 *
    014 * Unless required by applicable law or agreed to in writing,
    015 * software distributed under the License is distributed on an
    016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    017 * KIND, either express or implied.  See the License for the
    018 * specific language governing permissions and limitations
    019 * under the License.
    020 */
    021
    022import org.apache.commons.logging.Log;
    023import org.apache.commons.logging.LogFactory;
    024import org.apache.turbine.annotation.TurbineLoader;
    025import org.apache.turbine.annotation.TurbineService;
    026import org.apache.turbine.modules.Screen;
    027import org.apache.turbine.modules.ScreenLoader;
    028import org.apache.turbine.pipeline.PipelineData;
    029import org.apache.turbine.services.TurbineServices;
    030import org.apache.turbine.services.template.TemplateService;
    031import org.apache.turbine.util.RunData;
    032import org.apache.turbine.util.template.TemplateInfo;
    033
    034/**
    035 * Template Screen.
    036 *
    037 * Base Template Screens should extend this class and override the
    038 * buildTemplate() method.  Users of the particular service can then
    039 * override the doBuildTemplate() for any specific pre-processing.
    040 * You can also override the doBuild() method in order to add extra
    041 * functionality to your system, but you need to make sure to at least
    042 * duplicate the existing functionality in order for things to work.
    043 * Look at the code for the doBuild() method to get an idea of what is
    044 * going on there (it is quite simple really).
    045 *
    046 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
    047 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    048 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
    049 * @version $Id: TemplateScreen.java 1773378 2016-12-09 13:19:59Z tv $
    050 */
    051public abstract class TemplateScreen
    052    extends Screen
    053{
    054    /** Logging */
    055    protected Log log = LogFactory.getLog(this.getClass());
    056
    057    /** Injected service instance */
    058    @TurbineService
    059    private TemplateService templateService;
    060
    061    /** Injected loader instance */
    062    @TurbineLoader( Screen.class )
    063    private ScreenLoader screenLoader;
    064
    065    /**
    066     * This method should be overridden by subclasses that wish to add
    067     * specific business logic.
    068     * @param pipelineData Turbine information.
    069     * @throws Exception A generic exception.
    070     */
    071    protected abstract void doBuildTemplate(PipelineData pipelineData)
    072            throws Exception;
    073
    074    /**
    075     * This method should be implemented by Base template classes.  It
    076     * should contain the specific template service code to generate
    077     * the template.
    078     * @param pipelineData Turbine information.
    079     * @return the content of the screen
    080     * @throws Exception A generic exception.
    081     */
    082    public abstract String buildTemplate(PipelineData pipelineData)
    083            throws Exception;
    084
    085    /**
    086     * This method can be overridden to write code that executes when
    087     * the template has been built (called from a finally clause, so
    088     * executes regardless of whether an exception is thrown or not)
    089     *
    090     * @param pipelineData Turbine information
    091     */
    092    protected void doPostBuildTemplate(PipelineData pipelineData)
    093    {
    094        // empty
    095    }
    096
    097    /**
    098     * This method is called by the Screenloader to construct the
    099     * Screen.
    100     *
    101     * @param pipelineData Turbine information.
    102     * @return the content of the screen
    103     * @throws Exception A generic exception.
    104     */
    105    @Override
    106    protected String doBuild(PipelineData pipelineData)
    107            throws Exception
    108    {
    109        String out = null;
    110
    111        try
    112        {
    113            doBuildTemplate(pipelineData);
    114            out = buildTemplate(pipelineData);
    115        }
    116        finally
    117        {
    118            doPostBuildTemplate(pipelineData);
    119        }
    120
    121        return out;
    122    }
    123
    124    /**
    125     * This method is used when you want to short circuit a Screen and
    126     * change the template that will be executed next. <b>Note that the current
    127     * context will be applied to the next template that is executed.
    128     * If you want to have the context executed for the next screen,
    129     * to be the same one as the next screen, then you should use the
    130     * TemplateScreen.doRedirect() method.</b>
    131     *
    132     * @param pipelineData Turbine information.
    133     * @param template The name of the next template.
    134     */
    135    public static void setTemplate(PipelineData pipelineData, String template)
    136    {
    137        RunData data = (RunData)pipelineData;
    138        TemplateInfo ti = data.getTemplateInfo();
    139        TemplateService templateService = (TemplateService)TurbineServices.getInstance().getService(TemplateService.SERVICE_NAME);
    140
    141        ti.setScreenTemplate(template);
    142        try
    143        {
    144            // We have do call getScreenTemplate because of the path
    145            // separator.
    146            ti.setLayoutTemplate(templateService.getLayoutTemplateName(ti.getScreenTemplate()));
    147        }
    148        catch (Exception e)
    149        {
    150            // Nothing to do.
    151        }
    152    }
    153
    154    /**
    155     * You can call this within a Screen to cause an internal redirect
    156     * to happen.  It essentially allows you to stop execution in one
    157     * Screen and instantly execute another Screen.  Don't worry, this
    158     * does not do a HTTP redirect and also if you have anything added
    159     * in the Context, it will get carried over.
    160     *
    161     * <p>
    162     *
    163     * This class is useful if you have a Screen that submits to
    164     * another Screen and you want it to do error validation before
    165     * executing the other Screen.  If there is an error, you can
    166     * doRedirect() back to the original Screen.
    167     *
    168     * @param pipelineData Turbine information.
    169     * @param screen Name of screen to redirect to.
    170     * @param template Name of template.
    171     * @throws Exception A generic exception.
    172     */
    173    public void doRedirect(PipelineData pipelineData, String screen, String template)
    174            throws Exception
    175    {
    176        log.debug("doRedirect(data, " + screen + ", " + template + ")");
    177        setTemplate(pipelineData, template);
    178        screenLoader.exec(pipelineData, screen);
    179    }
    180
    181    /**
    182     * You can call this within a Screen to cause an internal redirect
    183     * to happen.  It essentially allows you to stop execution in one
    184     * Screen and instantly execute another Screen.  Don't worry, this
    185     * does not do a HTTP redirect and also if you have anything added
    186     * in the Context, it will get carried over.
    187     *
    188     * <p>
    189     *
    190     * This class is useful if you have a Screen that submits to
    191     * another Screen and you want it to do error validation before
    192     * executing the other Screen.  If there is an error, you can
    193     * doRedirect() back to the original Screen.
    194     *
    195     * @param pipelineData Turbine information.
    196     * @param template Name of template.
    197     * @throws Exception A generic exception.
    198     */
    199    public void doRedirect(PipelineData pipelineData, String template)
    200            throws Exception
    201    {
    202        doRedirect(pipelineData, templateService.getScreenName(template), template);
    203    }
    204}