1 package org.apache.turbine.modules.screens;
2
3 import org.apache.logging.log4j.LogManager;
4
5 /*
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 */
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.turbine.annotation.TurbineLoader;
26 import org.apache.turbine.annotation.TurbineService;
27 import org.apache.turbine.modules.Screen;
28 import org.apache.turbine.modules.ScreenLoader;
29 import org.apache.turbine.pipeline.PipelineData;
30 import org.apache.turbine.services.TurbineServices;
31 import org.apache.turbine.services.template.TemplateService;
32 import org.apache.turbine.util.RunData;
33 import org.apache.turbine.util.template.TemplateInfo;
34
35 /**
36 * Template Screen.
37 *
38 * Base Template Screens should extend this class and override the
39 * buildTemplate() method. Users of the particular service can then
40 * override the doBuildTemplate() for any specific pre-processing.
41 * You can also override the doBuild() method in order to add extra
42 * functionality to your system, but you need to make sure to at least
43 * duplicate the existing functionality in order for things to work.
44 * Look at the code for the doBuild() method to get an idea of what is
45 * going on there (it is quite simple really).
46 *
47 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
48 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
49 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
50 * @version $Id$
51 */
52 public abstract class TemplateScreen implements Screen
53 {
54 /** Logging */
55 protected Logger log = LogManager.getLogger(this.getClass());
56
57 /** Injected service instance */
58 @TurbineService
59 private TemplateService templateService;
60
61 /** Injected loader instance */
62 @TurbineLoader( Screen.class )
63 private ScreenLoader screenLoader;
64
65 /**
66 * This method should be overridden by subclasses that wish to add
67 * specific business logic.
68 * @param pipelineData Turbine information.
69 * @throws Exception A generic exception.
70 */
71 protected abstract void doBuildTemplate(PipelineData pipelineData)
72 throws Exception;
73
74 /**
75 * This method should be implemented by Base template classes. It
76 * should contain the specific template service code to generate
77 * the template.
78 * @param pipelineData Turbine information.
79 * @return the content of the screen
80 * @throws Exception A generic exception.
81 */
82 public abstract String buildTemplate(PipelineData pipelineData)
83 throws Exception;
84
85 /**
86 * This method can be overridden to write code that executes when
87 * the template has been built (called from a finally clause, so
88 * executes regardless of whether an exception is thrown or not)
89 *
90 * @param pipelineData Turbine information
91 */
92 protected void doPostBuildTemplate(PipelineData pipelineData)
93 {
94 // empty
95 }
96
97 /**
98 * This method is called by the Screenloader to construct the
99 * Screen.
100 *
101 * @param pipelineData Turbine information.
102 * @return the content of the screen
103 * @throws Exception A generic exception.
104 */
105 @Override
106 public 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 }