1 /* 2 * Copyright 2003,2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.struts.chain; 18 19 20 import org.apache.commons.beanutils.DynaBean; 21 import org.apache.commons.chain.Command; 22 import org.apache.commons.chain.Context; 23 import org.apache.commons.chain.web.WebContext; 24 import org.apache.struts.action.ActionForm; 25 import org.apache.struts.action.ActionMapping; 26 import org.apache.struts.action.ActionServlet; 27 import org.apache.struts.action.DynaActionForm; 28 import org.apache.struts.action.DynaActionFormClass; 29 import org.apache.struts.chain.Constants; 30 import org.apache.struts.chain.util.ClassUtils; 31 import org.apache.struts.config.ActionConfig; 32 import org.apache.struts.config.FormBeanConfig; 33 import org.apache.struts.config.ModuleConfig; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 37 38 /** 39 * <p>Create (if necessary) and cache a form bean for this request.</p> 40 * 41 * @author Craig R. McClanahan 42 * @version $Rev: 54933 $ $Date: 2004-10-16 18:04:52 +0100 (Sat, 16 Oct 2004) $ 43 */ 44 45 public class CreateActionForm implements Command { 46 47 48 // ------------------------------------------------------ Instance Variables 49 50 51 private String actionConfigKey = Constants.ACTION_CONFIG_KEY; 52 private String actionFormKey = Constants.ACTION_FORM_KEY; 53 private String actionServletKey = Constants.ACTION_SERVLET_KEY; 54 private String moduleConfigKey = Constants.MODULE_CONFIG_KEY; 55 56 private static final Log log = 57 LogFactory.getLog(CreateActionForm.class); 58 59 // -------------------------------------------------------------- Properties 60 61 62 /** 63 * <p>Return the context attribute key under which the 64 * <code>ActionConfig</code> for the currently selected application 65 * action is stored.</p> 66 */ 67 public String getActionConfigKey() { 68 69 return (this.actionConfigKey); 70 71 } 72 73 74 /** 75 * <p>Set the context attribute key under which the 76 * <code>ActionConfig</code> for the currently selected application 77 * action is stored.</p> 78 * 79 * @param actionConfigKey The new context attribute key 80 */ 81 public void setActionConfigKey(String actionConfigKey) { 82 83 this.actionConfigKey = actionConfigKey; 84 85 } 86 87 88 /** 89 * <p>Return the context attribute key under which the 90 * <code>ActionForm</code> for the currently selected application 91 * action is stored.</p> 92 */ 93 public String getActionFormKey() { 94 95 return (this.actionFormKey); 96 97 } 98 99 100 /** 101 * <p>Set the context attribute key under which the 102 * <code>ActionForm</code> for the currently selected application 103 * action is stored.</p> 104 * 105 * @param actionFormKey The new context attribute key 106 */ 107 public void setActionFormKey(String actionFormKey) { 108 109 this.actionFormKey = actionFormKey; 110 111 } 112 113 114 /** 115 * <p>Return the context attribute key under which the 116 * <code>ActionServlet</code> for the currently selected application 117 * action is stored.</p> 118 */ 119 public String getActionServletKey() { 120 121 return (this.actionServletKey); 122 123 } 124 125 126 /** 127 * <p>Set the context attribute key under which the 128 * <code>ActionServlet</code> for the currently selected application 129 * action is stored.</p> 130 * 131 * @param actionServletKey The new context attribute key 132 */ 133 public void setActionServletKey(String actionServletKey) { 134 135 this.actionServletKey = actionServletKey; 136 137 } 138 139 /** 140 * <p>Return the context attribute key under which the 141 * <code>ModuleConfig</code> for the currently selected application 142 * module is stored.</p> 143 */ 144 public String getModuleConfigKey() { 145 146 return (this.moduleConfigKey); 147 148 } 149 150 151 /** 152 * <p>Set the context attribute key under which the 153 * <code>ModuleConfig</code> for the currently selected application 154 * module is stored.</p> 155 * 156 * @param moduleConfigKey The new context attribute key 157 */ 158 public void setModuleConfigKey(String moduleConfigKey) { 159 160 this.moduleConfigKey = moduleConfigKey; 161 162 } 163 164 165 // ---------------------------------------------------------- Public Methods 166 167 168 /** 169 * <p>Create (if necessary) and cache a form bean for this request.</p> 170 * 171 * @param context The <code>Context</code> for the current request 172 * 173 * @return <code>false</code> so that processing continues 174 */ 175 public boolean execute(Context context) throws Exception { 176 177 // Is there a form bean associated with this ActionConfig? 178 ActionConfig actionConfig = (ActionConfig) 179 context.get(getActionConfigKey()); 180 String name = actionConfig.getName(); 181 if (name == null) { 182 context.remove(getActionFormKey()); 183 return (false); 184 } 185 186 log.trace("Look up form-bean " + name); 187 188 // Look up the corresponding FormBeanConfig (if any) 189 FormBeanConfig formBeanConfig = 190 actionConfig.getModuleConfig().findFormBeanConfig(name); 191 if (formBeanConfig == null) { 192 log.warn("No FormBeanConfig found in module " 193 + actionConfig.getModuleConfig().getPrefix() 194 + " under name " + name); 195 context.remove(getActionFormKey()); 196 return (false); 197 } 198 199 // Look up the session scope ActionForm instance (if any) 200 WebContext wcontext = (WebContext) context; 201 ActionForm instance = null; 202 if ("session".equals(actionConfig.getScope())) { 203 instance = (ActionForm) 204 wcontext.getSessionScope().get(actionConfig.getAttribute()); 205 } 206 207 // Can we recycle the existing instance (if any)? 208 if (instance != null) { 209 log.trace("Found an instance in the session; test for reusability"); 210 if (formBeanConfig.getDynamic()) { 211 String className = 212 ((DynaBean) instance).getDynaClass().getName(); 213 if (className.equals(formBeanConfig.getName())) { 214 wcontext.put 215 (getActionFormKey(), instance); 216 /* It should already be in session scope 217 if ("session".equals(actionConfig.getScope())) { 218 wcontext.getSessionScope().put 219 (actionConfig.getAttribute(), instance); 220 } 221 */ 222 log.debug("Using existing instance (dynamic)"); 223 return (false); 224 } 225 } else { 226 try { 227 Class configClass = 228 ClassUtils.getApplicationClass 229 (formBeanConfig.getType()); 230 if (configClass.isAssignableFrom(instance.getClass())) { 231 wcontext.put 232 (getActionFormKey(), instance); 233 /* It should already be in session scope 234 if ("session".equals(actionConfig.getScope())) { 235 wcontext.getSessionScope().put 236 (actionConfig.getAttribute(), instance); 237 } 238 */ 239 log.debug("Using existing instance (non-dynamic)"); 240 return (false); 241 } 242 } catch (Exception e) { 243 log.debug("Error testing existing instance for reusability; just create a new instance", e); 244 } 245 } 246 } 247 248 log.trace("Make a new instance of: " + formBeanConfig); 249 // Create a new form bean instance 250 if (formBeanConfig.getDynamic()) { 251 ModuleConfig moduleConfig = (ModuleConfig) 252 wcontext.get(getModuleConfigKey()); 253 DynaActionFormClass dynaClass = 254 DynaActionFormClass.createDynaActionFormClass(formBeanConfig); 255 instance = (ActionForm) dynaClass.newInstance(); 256 ((DynaActionForm) instance).initialize 257 ((ActionMapping) actionConfig); 258 } else { 259 instance = (ActionForm) 260 ClassUtils.getApplicationInstance(formBeanConfig.getType()); 261 } 262 263 // Configure and cache the new instance 264 ActionServlet servlet = (ActionServlet) 265 wcontext.get(getActionServletKey()); 266 instance.setServlet(servlet); 267 wcontext.put(getActionFormKey(), instance); 268 if ("session".equals(actionConfig.getScope())) { 269 wcontext.getSessionScope().put 270 (actionConfig.getAttribute(), instance); 271 } else if ("request".equals(actionConfig.getScope())) { 272 wcontext.getRequestScope().put 273 (actionConfig.getAttribute(), instance); 274 } 275 276 return (false); 277 278 } 279 280 281 }