001package org.apache.turbine.modules.screens; 002 003import org.apache.logging.log4j.LogManager; 004 005/* 006 * Licensed to the Apache Software Foundation (ASF) under one 007 * or more contributor license agreements. See the NOTICE file 008 * distributed with this work for additional information 009 * regarding copyright ownership. The ASF licenses this file 010 * to you under the Apache License, Version 2.0 (the 011 * "License"); you may not use this file except in compliance 012 * with the License. You may obtain a copy of the License at 013 * 014 * http://www.apache.org/licenses/LICENSE-2.0 015 * 016 * Unless required by applicable law or agreed to in writing, 017 * software distributed under the License is distributed on an 018 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 019 * KIND, either express or implied. See the License for the 020 * specific language governing permissions and limitations 021 * under the License. 022 */ 023 024import org.apache.logging.log4j.Logger; 025import org.apache.turbine.annotation.TurbineLoader; 026import org.apache.turbine.annotation.TurbineService; 027import org.apache.turbine.modules.Screen; 028import org.apache.turbine.modules.ScreenLoader; 029import org.apache.turbine.pipeline.PipelineData; 030import org.apache.turbine.services.TurbineServices; 031import org.apache.turbine.services.template.TemplateService; 032import org.apache.turbine.util.RunData; 033import org.apache.turbine.util.template.TemplateInfo; 034 035/** 036 * Template Screen. 037 * 038 * Base Template Screens should extend this class and override the 039 * buildTemplate() method. Users of the particular service can then 040 * override the doBuildTemplate() for any specific pre-processing. 041 * You can also override the doBuild() method in order to add extra 042 * functionality to your system, but you need to make sure to at least 043 * duplicate the existing functionality in order for things to work. 044 * Look at the code for the doBuild() method to get an idea of what is 045 * going on there (it is quite simple really). 046 * 047 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> 048 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 049 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> 050 * @version $Id$ 051 */ 052public abstract class TemplateScreen implements Screen 053{ 054 /** Logging */ 055 protected Logger log = LogManager.getLogger(this.getClass()); 056 057 /** Injected service instance */ 058 @TurbineService 059 private TemplateService templateService; 060 061 /** Injected loader instance */ 062 @TurbineLoader( Screen.class ) 063 private ScreenLoader screenLoader; 064 065 /** 066 * This method should be overridden by subclasses that wish to add 067 * specific business logic. 068 * @param pipelineData Turbine information. 069 * @throws Exception A generic exception. 070 */ 071 protected abstract void doBuildTemplate(PipelineData pipelineData) 072 throws Exception; 073 074 /** 075 * This method should be implemented by Base template classes. It 076 * should contain the specific template service code to generate 077 * the template. 078 * @param pipelineData Turbine information. 079 * @return the content of the screen 080 * @throws Exception A generic exception. 081 */ 082 public abstract String buildTemplate(PipelineData pipelineData) 083 throws Exception; 084 085 /** 086 * This method can be overridden to write code that executes when 087 * the template has been built (called from a finally clause, so 088 * executes regardless of whether an exception is thrown or not) 089 * 090 * @param pipelineData Turbine information 091 */ 092 protected void doPostBuildTemplate(PipelineData pipelineData) 093 { 094 // empty 095 } 096 097 /** 098 * This method is called by the Screenloader to construct the 099 * 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}