1 /* 2 * Copyright (c) 2002-2006 by OpenSymphony 3 * All rights reserved. 4 */ 5 package com.opensymphony.xwork2.interceptor; 6 7 import com.opensymphony.xwork2.ActionContext; 8 import com.opensymphony.xwork2.ActionInvocation; 9 import com.opensymphony.xwork2.ObjectFactory; 10 import com.opensymphony.xwork2.XWorkException; 11 import com.opensymphony.xwork2.config.entities.ActionConfig; 12 import com.opensymphony.xwork2.inject.Inject; 13 14 import java.lang.reflect.Method; 15 import java.util.Map; 16 17 /** 18 * <!-- START SNIPPET: description --> 19 * 20 * An interceptor that enables scoped model-driven actions. 21 * 22 * <p/>This interceptor only activates on actions that implement the {@link ScopedModelDriven} interface. If 23 * detected, it will retrieve the model class from the configured scope, then provide it to the Action. 24 * 25 * <!-- END SNIPPET: description --> 26 * 27 * <p/> <u>Interceptor parameters:</u> 28 * 29 * <!-- START SNIPPET: parameters --> 30 * 31 * <ul> 32 * 33 * <li>className - The model class name. Defaults to the class name of the object returned by the getModel() method.</li> 34 * 35 * <li>name - The key to use when storing or retrieving the instance in a scope. Defaults to the model 36 * class name.</li> 37 * 38 * <li>scope - The scope to store and retrieve the model. Defaults to 'request' but can also be 'session'.</li> 39 * </ul> 40 * 41 * <!-- END SNIPPET: parameters --> 42 * 43 * <p/> <u>Extending the interceptor:</u> 44 * 45 * <p/> 46 * 47 * <!-- START SNIPPET: extending --> 48 * 49 * There are no known extension points for this interceptor. 50 * 51 * <!-- END SNIPPET: extending --> 52 * 53 * <p/> <u>Example code:</u> 54 * 55 * <pre> 56 * <!-- START SNIPPET: example --> 57 * 58 * <-- Basic usage --> 59 * <interceptor name="scopedModelDriven" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor" /> 60 * 61 * <-- Using all available parameters --> 62 * <interceptor name="gangsterForm" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor"> 63 * <param name="scope">session</param> 64 * <param name="name">gangsterForm</param> 65 * <param name="className">com.opensymphony.example.GangsterForm</param> 66 * </interceptor> 67 * 68 * <!-- END SNIPPET: example --> 69 * </pre> 70 */ 71 public class ScopedModelDrivenInterceptor extends AbstractInterceptor { 72 73 private static final String GET_MODEL = "getModel"; 74 private String scope; 75 private String name; 76 private String className; 77 private ObjectFactory objectFactory; 78 79 @Inject 80 public void setObjectFactory(ObjectFactory factory) { 81 this.objectFactory = factory; 82 } 83 84 protected Object resolveModel(ObjectFactory factory, ActionContext actionContext, String modelClassName, String modelScope, String modelName) throws Exception { 85 Object model = null; 86 Map<String, Object> scopeMap = actionContext.getContextMap(); 87 if ("session".equals(modelScope)) { 88 scopeMap = actionContext.getSession(); 89 } 90 91 model = scopeMap.get(modelName); 92 if (model == null) { 93 model = factory.buildBean(modelClassName, null); 94 scopeMap.put(modelName, model); 95 } 96 return model; 97 } 98 99 @Override 100 public String intercept(ActionInvocation invocation) throws Exception { 101 Object action = invocation.getAction(); 102 103 if (action instanceof ScopedModelDriven) { 104 ScopedModelDriven modelDriven = (ScopedModelDriven) action; 105 if (modelDriven.getModel() == null) { 106 ActionContext ctx = ActionContext.getContext(); 107 ActionConfig config = invocation.getProxy().getConfig(); 108 109 String cName = className; 110 if (cName == null) { 111 try { 112 Method method = action.getClass().getMethod(GET_MODEL, new Class[0]); 113 Class cls = method.getReturnType(); 114 cName = cls.getName(); 115 } catch (NoSuchMethodException e) { 116 throw new XWorkException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config); 117 } 118 } 119 String modelName = name; 120 if (modelName == null) { 121 modelName = cName; 122 } 123 Object model = resolveModel(objectFactory, ctx, cName, scope, modelName); 124 modelDriven.setModel(model); 125 modelDriven.setScopeKey(modelName); 126 } 127 } 128 return invocation.invoke(); 129 } 130 131 /** 132 * @param className the className to set 133 */ 134 public void setClassName(String className) { 135 this.className = className; 136 } 137 138 /** 139 * @param name the name to set 140 */ 141 public void setName(String name) { 142 this.name = name; 143 } 144 145 /** 146 * @param scope the scope to set 147 */ 148 public void setScope(String scope) { 149 this.scope = scope; 150 } 151 }