/* * Copyright 2002-2006,2009 The Apache Software Foundation. * * Licensed 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.XWorkException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.inject.Inject; 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. * * <!-- END SNIPPET: description --> * * <p/> <u>Interceptor parameters:</u> * * <!-- 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> * * <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 = null; 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 XWorkException("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; } }