    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.template.TemplateService;
    030import org.apache.turbine.services.template.TurbineTemplate;
    031import org.apache.turbine.util.RunData;
    032
    033/**
    034 * Template Screen.
    035 *
    036 * Base Template Screens should extend this class and override the
    037 * buildTemplate() method.  Users of the particular service can then
    038 * override the doBuildTemplate() for any specific pre-processing.
    039 * You can also override the doBuild() method in order to add extra
    040 * functionality to your system, but you need to make sure to at least
    041 * duplicate the existing functionality in order for things to work.
    042 * Look at the code for the doBuild() method to get an idea of what is
    043 * going on there (it is quite simple really).
    044 *
    045 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
    046 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    047 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
    048 * @version $Id: TemplateScreen.java 1709648 2015-10-20 17:08:10Z tv $
    049 */
    050public abstract class TemplateScreen
    051    extends Screen
    052{
    053    /** Logging */
    054    protected Log log = LogFactory.getLog(this.getClass());
    055
    056    /** Injected service instance */
    057    @TurbineService
    058    private TemplateService templateService;
    059
    060    /** Injected loader instance */
    061    @TurbineLoader( Screen.class )
    062    private ScreenLoader screenLoader;
    063
    064    /**
    065     * This method should be overridden by subclasses that wish to add
    066     * specific business logic.
    067     * @param pipelineData Turbine information.
    068     * @exception Exception A generic exception.
    069     */
    070    protected abstract void doBuildTemplate(PipelineData pipelineData)
    071            throws Exception;
    072
    073    /**
    074     * This method should be implemented by Base template classes.  It
    075     * should contain the specific template service code to generate
    076     * the template.
    077     * @param pipelineData Turbine information.
    078     * @return the content of the screen
    079     * @exception Exception A generic exception.
    080     */
    081    public abstract String buildTemplate(PipelineData pipelineData)
    082            throws Exception;
    083
    084    /**
    085     * This method can be overridden to write code that executes when
    086     * the template has been built (called from a finally clause, so
    087     * executes regardless of whether an exception is thrown or not)
    088     */
    089    protected void doPostBuildTemplate(PipelineData pipelineData)
    090    {
    091        // empty
    092    }
    093
    094    /**
    095     * This method is called by the Screenloader to construct the
    096     * Screen.
    097     *
    098     * @param pipelineData Turbine information.
    099     * @return the content of the screen
    100     * @exception Exception A generic exception.
    101     */
    102    @Override
    103    protected String doBuild(PipelineData pipelineData)
    104            throws Exception
    105    {
    106        String out = null;
    107
    108        try
    109        {
    110            doBuildTemplate(pipelineData);
    111            out = buildTemplate(pipelineData);
    112        }
    113        finally
    114        {
    115            doPostBuildTemplate(pipelineData);
    116        }
    117
    118        return out;
    119    }
    120
    121    /**
    122     * This method is used when you want to short circuit a Screen and
    123     * change the template that will be executed next. <b>Note that the current
    124     * context will be applied to the next template that is executed.
    125     * If you want to have the context executed for the next screen,
    126     * to be the same one as the next screen, then you should use the
    127     * TemplateScreen.doRedirect() method.</b>
    128     *
    129     * @param pipelineData Turbine information.
    130     * @param template The name of the next template.
    131     */
    132    public static void setTemplate(PipelineData pipelineData, String template)
    133    {
    134        RunData data = (RunData)pipelineData;
    135        data.getTemplateInfo().setScreenTemplate(template);
    136        try
    137        {
    138            // We have do call getScreenTemplate because of the path
    139            // separator.
    140            data.getTemplateInfo().setLayoutTemplate(
    141                    TurbineTemplate.getLayoutTemplateName(
    142                            data.getTemplateInfo().getScreenTemplate()));
    143        }
    144        catch (Exception e)
    145        {
    146            // Nothing to do.
    147        }
    148    }
    149
    150    /**
    151     * You can call this within a Screen to cause an internal redirect
    152     * to happen.  It essentially allows you to stop execution in one
    153     * Screen and instantly execute another Screen.  Don't worry, this
    154     * does not do a HTTP redirect and also if you have anything added
    155     * in the Context, it will get carried over.
    156     *
    157     * <p>
    158     *
    159     * This class is useful if you have a Screen that submits to
    160     * another Screen and you want it to do error validation before
    161     * executing the other Screen.  If there is an error, you can
    162     * doRedirect() back to the original Screen.
    163     *
    164     * @param pipelineData Turbine information.
    165     * @param screen Name of screen to redirect to.
    166     * @param template Name of template.
    167     * @exception Exception A generic exception.
    168     */
    169    public void doRedirect(PipelineData pipelineData, String screen, String template)
    170            throws Exception
    171    {
    172        log.debug("doRedirect(data, " + screen + ", " + template + ")");
    173        setTemplate(pipelineData, template);
    174        screenLoader.exec(pipelineData, screen);
    175    }
    176
    177    /**
    178     * You can call this within a Screen to cause an internal redirect
    179     * to happen.  It essentially allows you to stop execution in one
    180     * Screen and instantly execute another Screen.  Don't worry, this
    181     * does not do a HTTP redirect and also if you have anything added
    182     * in the Context, it will get carried over.
    183     *
    184     * <p>
    185     *
    186     * This class is useful if you have a Screen that submits to
    187     * another Screen and you want it to do error validation before
    188     * executing the other Screen.  If there is an error, you can
    189     * doRedirect() back to the original Screen.
    190     *
    191     * @param pipelineData Turbine information.
    192     * @param template Name of template.
    193     * @exception Exception A generic exception.
    194     */
    195    public void doRedirect(PipelineData pipelineData, String template)
    196            throws Exception
    197    {
    198        doRedirect(pipelineData, templateService.getScreenName(template), template);
    199    }
    200}