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}