001    package 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    
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    
025    import org.apache.ecs.ConcreteElement;
026    
027    import org.apache.turbine.modules.Screen;
028    import org.apache.turbine.modules.ScreenLoader;
029    import org.apache.turbine.pipeline.PipelineData;
030    
031    import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
032    import org.apache.turbine.services.template.TurbineTemplate;
033    
034    import org.apache.turbine.util.RunData;
035    
036    /**
037     * Template Screen.
038     *
039     * Base Template Screens should extend this class and override the
040     * buildTemplate() method.  Users of the particular service can then
041     * override the doBuildTemplate() for any specific pre-processing.
042     * You can also override the doBuild() method in order to add extra
043     * functionality to your system, but you need to make sure to at least
044     * duplicate the existing functionality in order for things to work.
045     * Look at the code for the doBuild() method to get an idea of what is
046     * going on there (it is quite simple really).
047     *
048     * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
049     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
050     * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
051     * @version $Id: TemplateScreen.java 938645 2010-04-27 20:57:51Z tv $
052     */
053    public abstract class TemplateScreen
054        extends Screen
055    {
056        /** Logging */
057        protected Log log = LogFactory.getLog(this.getClass());
058    
059        private ScreenLoader screenLoader;
060    
061        /**
062         * Default constructor
063         */
064        public TemplateScreen()
065        {
066            super();
067    
068            this.screenLoader = (ScreenLoader)TurbineAssemblerBroker.getLoader(NAME);
069        }
070    
071        /**
072         * This method should be overidden by subclasses that wish to add
073         * specific business logic.
074         *
075         * @deprecated Use PipelineData version instead.
076         * @param data Turbine information.
077         * @exception Exception A generic exception.
078         */
079        protected abstract void doBuildTemplate(RunData data)
080                throws Exception;
081    
082        /**
083         * This method should be overidden by subclasses that wish to add
084         * specific business logic.
085         * Should revert to abstract when RunData has gone.
086         * @param data Turbine information.
087         * @exception Exception A generic exception.
088         */
089        protected void doBuildTemplate(PipelineData pipelineData)
090        throws Exception
091        {
092            RunData data = getRunData(pipelineData);
093            doBuildTemplate(data);
094        }
095    
096    
097        /**
098         * This method should be implemented by Base template classes.  It
099         * should contain the specific template service code to generate
100         * the template.
101         *
102         * @deprecated Use PipelineData version instead.
103         * @param data Turbine information.
104         * @return A ConcreteElement.
105         * @exception Exception A generic exception.
106         */
107        public abstract ConcreteElement buildTemplate(RunData data)
108                throws Exception;
109    
110        /**
111         * This method should be implemented by Base template classes.  It
112         * should contain the specific template service code to generate
113         * the template.
114         * Should revert to abstract when RunData goes.
115         * @param data Turbine information.
116         * @return A ConcreteElement.
117         * @exception Exception A generic exception.
118         */
119        public ConcreteElement buildTemplate(PipelineData pipelineData)
120        throws Exception
121        {
122            RunData data = getRunData(pipelineData);
123            return buildTemplate(data);
124        }
125    
126    
127        /**
128         * This method can be overridden to write code that executes when
129         * the template has been built (called from a finally clause, so
130         * executes regardless of whether an exception is thrown or not)
131         *
132         * @deprecated Use PipelineData version instead.
133         */
134        protected void doPostBuildTemplate(RunData data)
135        {
136            // empty
137        }
138    
139        /**
140         * This method can be overridden to write code that executes when
141         * the template has been built (called from a finally clause, so
142         * executes regardless of whether an exception is thrown or not)
143         */
144        protected void doPostBuildTemplate(PipelineData pipelineData)
145        {
146            // empty
147        }
148    
149    
150        /**
151         * This method is called by the Screenloader to construct the
152         * Screen.
153         *
154         * @deprecated Use PipelineData version instead.
155         * @param data Turbine information.
156         * @return A ConcreteElement.
157         * @exception Exception A generic exception.
158         */
159        protected ConcreteElement doBuild(RunData data)
160                throws Exception
161        {
162            ConcreteElement out = null;
163    
164            try
165            {
166                doBuildTemplate(data);
167                out = buildTemplate(data);
168            }
169            finally
170            {
171                doPostBuildTemplate(data);
172            }
173    
174            return out;
175        }
176    
177        /**
178         * This method is called by the Screenloader to construct the
179         * Screen.
180         *
181         * @param data Turbine information.
182         * @return A ConcreteElement.
183         * @exception Exception A generic exception.
184         */
185        protected ConcreteElement doBuild(PipelineData pipelineData)
186                throws Exception
187        {
188            ConcreteElement out = null;
189    
190            try
191            {
192                doBuildTemplate(pipelineData);
193                out = buildTemplate(pipelineData);
194            }
195            finally
196            {
197                doPostBuildTemplate(pipelineData);
198            }
199    
200            return out;
201        }
202    
203    
204    
205        /**
206         * This method is used when you want to short circuit a Screen and
207         * change the template that will be executed next. <b>Note that the current
208         * context will be applied to the next template that is executed.
209         * If you want to have the context executed for the next screen,
210         * to be the same one as the next screen, then you should use the
211         * TemplateScreen.doRedirect() method.</b>
212         *
213         * @deprecated Use PipelineData version instead.
214         * @param data Turbine information.
215         * @param template The name of the next template.
216         */
217        public static void setTemplate(RunData data, String template)
218        {
219            data.getTemplateInfo().setScreenTemplate(template);
220            try
221            {
222                // We have do call getScreenTemplate because of the path
223                // separator.
224                data.getTemplateInfo().setLayoutTemplate(
225                        TurbineTemplate.getLayoutTemplateName(
226                                data.getTemplateInfo().getScreenTemplate()));
227            }
228            catch (Exception e)
229            {
230                // Nothing to do.
231            }
232        }
233    
234        /**
235         * This method is used when you want to short circuit a Screen and
236         * change the template that will be executed next. <b>Note that the current
237         * context will be applied to the next template that is executed.
238         * If you want to have the context executed for the next screen,
239         * to be the same one as the next screen, then you should use the
240         * TemplateScreen.doRedirect() method.</b>
241         *
242         * @param data Turbine information.
243         * @param template The name of the next template.
244         */
245        public static void setTemplate(PipelineData pipelineData, String template)
246        {
247            //Map runDataMap = (Map) pipelineData.get(RunData.class);
248            //RunData data = (RunData)runDataMap.get(RunData.class);
249            RunData data = (RunData)pipelineData;
250            setTemplate(data, template);
251        }
252    
253        /**
254         * You can call this within a Screen to cause an internal redirect
255         * to happen.  It essentially allows you to stop execution in one
256         * Screen and instantly execute another Screen.  Don't worry, this
257         * does not do a HTTP redirect and also if you have anything added
258         * in the Context, it will get carried over.
259         *
260         * <p>
261         *
262         * This class is useful if you have a Screen that submits to
263         * another Screen and you want it to do error validation before
264         * executing the other Screen.  If there is an error, you can
265         * doRedirect() back to the original Screen.
266         *
267         * @deprecated Use PipelineData version instead.
268         * @param data Turbine information.
269         * @param screen Name of screen to redirect to.
270         * @param template Name of template.
271         * @exception Exception A generic exception.
272         */
273        public void doRedirect(RunData data, String screen, String template)
274                throws Exception
275        {
276            log.debug("doRedirect(data, " + screen + ", " + template + ")");
277            setTemplate(data, template);
278            screenLoader.exec(data, screen);
279        }
280    
281        /**
282         * You can call this within a Screen to cause an internal redirect
283         * to happen.  It essentially allows you to stop execution in one
284         * Screen and instantly execute another Screen.  Don't worry, this
285         * does not do a HTTP redirect and also if you have anything added
286         * in the Context, it will get carried over.
287         *
288         * <p>
289         *
290         * This class is useful if you have a Screen that submits to
291         * another Screen and you want it to do error validation before
292         * executing the other Screen.  If there is an error, you can
293         * doRedirect() back to the original Screen.
294         *
295         * @param data Turbine information.
296         * @param screen Name of screen to redirect to.
297         * @param template Name of template.
298         * @exception Exception A generic exception.
299         */
300        public void doRedirect(PipelineData pipelineData, String screen, String template)
301                throws Exception
302        {
303            RunData data = getRunData(pipelineData);
304            log.debug("doRedirect(data, " + screen + ", " + template + ")");
305            setTemplate(data, template);
306            screenLoader.exec(pipelineData, screen);
307        }
308    
309    
310        /**
311         * You can call this within a Screen to cause an internal redirect
312         * to happen.  It essentially allows you to stop execution in one
313         * Screen and instantly execute another Screen.  Don't worry, this
314         * does not do a HTTP redirect and also if you have anything added
315         * in the Context, it will get carried over.
316         *
317         * <p>
318         *
319         * This class is useful if you have a Screen that submits to
320         * another Screen and you want it to do error validation before
321         * executing the other Screen.  If there is an error, you can
322         * doRedirect() back to the original Screen.
323         *
324         * @deprecated Use PipelineData version instead.
325         * @param data Turbine information.
326         * @param template Name of template.
327         * @exception Exception A generic exception.
328         */
329        public void doRedirect(RunData data, String template)
330                throws Exception
331        {
332            doRedirect(data, TurbineTemplate.getScreenName(template), template);
333        }
334    
335        /**
336         * You can call this within a Screen to cause an internal redirect
337         * to happen.  It essentially allows you to stop execution in one
338         * Screen and instantly execute another Screen.  Don't worry, this
339         * does not do a HTTP redirect and also if you have anything added
340         * in the Context, it will get carried over.
341         *
342         * <p>
343         *
344         * This class is useful if you have a Screen that submits to
345         * another Screen and you want it to do error validation before
346         * executing the other Screen.  If there is an error, you can
347         * doRedirect() back to the original Screen.
348         *
349         * @param data Turbine information.
350         * @param template Name of template.
351         * @exception Exception A generic exception.
352         */
353        public void doRedirect(PipelineData pipelineData, String template)
354                throws Exception
355        {
356            doRedirect(pipelineData, template);
357        }
358    
359    
360    }