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