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 }