| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package com.opensymphony.xwork2.interceptor; |
| |
| import com.opensymphony.xwork2.ActionContext; |
| import com.opensymphony.xwork2.ActionInvocation; |
| import com.opensymphony.xwork2.ObjectFactory; |
| import com.opensymphony.xwork2.config.entities.ActionConfig; |
| import com.opensymphony.xwork2.inject.Inject; |
| import org.apache.struts2.StrutsException; |
| |
| import java.lang.reflect.Method; |
| import java.util.Map; |
| |
| /** |
| * <!-- START SNIPPET: description --> |
| * |
| * An interceptor that enables scoped model-driven actions. |
| * |
| * <p>This interceptor only activates on actions that implement the {@link ScopedModelDriven} interface. If |
| * detected, it will retrieve the model class from the configured scope, then provide it to the Action.</p> |
| * |
| * <!-- END SNIPPET: description --> |
| * |
| * <p><u>Interceptor parameters:</u></p> |
| * |
| * <!-- START SNIPPET: parameters --> |
| * |
| * <ul> |
| * |
| * <li>className - The model class name. Defaults to the class name of the object returned by the getModel() method.</li> |
| * |
| * <li>name - The key to use when storing or retrieving the instance in a scope. Defaults to the model |
| * class name.</li> |
| * |
| * <li>scope - The scope to store and retrieve the model. Defaults to 'request' but can also be 'session'.</li> |
| * </ul> |
| * |
| * <!-- END SNIPPET: parameters --> |
| * |
| * <p><u>Extending the interceptor:</u></p> |
| * |
| * <!-- START SNIPPET: extending --> |
| * |
| * There are no known extension points for this interceptor. |
| * |
| * <!-- END SNIPPET: extending --> |
| * |
| * <p><u>Example code:</u></p> |
| * |
| * <pre> |
| * <!-- START SNIPPET: example --> |
| * |
| * <-- Basic usage --> |
| * <interceptor name="scopedModelDriven" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor" /> |
| * |
| * <-- Using all available parameters --> |
| * <interceptor name="gangsterForm" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor"> |
| * <param name="scope">session</param> |
| * <param name="name">gangsterForm</param> |
| * <param name="className">com.opensymphony.example.GangsterForm</param> |
| * </interceptor> |
| * |
| * <!-- END SNIPPET: example --> |
| * </pre> |
| */ |
| public class ScopedModelDrivenInterceptor extends AbstractInterceptor { |
| |
| private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; |
| |
| private static final String GET_MODEL = "getModel"; |
| private String scope; |
| private String name; |
| private String className; |
| private ObjectFactory objectFactory; |
| |
| @Inject |
| public void setObjectFactory(ObjectFactory factory) { |
| this.objectFactory = factory; |
| } |
| |
| protected Object resolveModel(ObjectFactory factory, ActionContext actionContext, String modelClassName, String modelScope, String modelName) throws Exception { |
| Object model; |
| Map<String, Object> scopeMap = actionContext.getContextMap(); |
| if ("session".equals(modelScope)) { |
| scopeMap = actionContext.getSession(); |
| } |
| |
| model = scopeMap.get(modelName); |
| if (model == null) { |
| model = factory.buildBean(modelClassName, null); |
| scopeMap.put(modelName, model); |
| } |
| return model; |
| } |
| |
| @Override |
| public String intercept(ActionInvocation invocation) throws Exception { |
| Object action = invocation.getAction(); |
| |
| if (action instanceof ScopedModelDriven) { |
| ScopedModelDriven modelDriven = (ScopedModelDriven) action; |
| if (modelDriven.getModel() == null) { |
| ActionContext ctx = ActionContext.getContext(); |
| ActionConfig config = invocation.getProxy().getConfig(); |
| |
| String cName = className; |
| if (cName == null) { |
| try { |
| Method method = action.getClass().getMethod(GET_MODEL, EMPTY_CLASS_ARRAY); |
| Class cls = method.getReturnType(); |
| cName = cls.getName(); |
| } catch (NoSuchMethodException e) { |
| throw new StrutsException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config); |
| } |
| } |
| String modelName = name; |
| if (modelName == null) { |
| modelName = cName; |
| } |
| Object model = resolveModel(objectFactory, ctx, cName, scope, modelName); |
| modelDriven.setModel(model); |
| modelDriven.setScopeKey(modelName); |
| } |
| } |
| return invocation.invoke(); |
| } |
| |
| /** |
| * @param className the className to set |
| */ |
| public void setClassName(String className) { |
| this.className = className; |
| } |
| |
| /** |
| * @param name the name to set |
| */ |
| public void setName(String name) { |
| this.name = name; |
| } |
| |
| /** |
| * @param scope the scope to set |
| */ |
| public void setScope(String scope) { |
| this.scope = scope; |
| } |
| } |