📄 multiaction.java
字号:
/*
* Copyright 2002-2005 the original author or authors.
*
* 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 org.springframework.webflow.action;
import org.springframework.binding.AttributeSource;
import org.springframework.webflow.Event;
import org.springframework.webflow.RequestContext;
import org.springframework.webflow.util.DispatchMethodInvoker;
/**
* Action implementation that bundles two or more action execution methods into a
* single class. Action execution methods defined by subclasses must adhere
* to the following signature:
*
* <pre>
* public Event ${method}(RequestContext context) throws Exception;
* </pre>
*
* When this action is invoked, by default the <code>id</code> of the calling
* action state state is treated as the action execution method name. Alternatively,
* the execution method name may be explicitly specified as a property of
* the calling action state.
* <p>
* For example, the following action state definition:
* <pre>
* <action-state id="search">
* <action bean="my.search.action"/>
* <transition on="success" to="results"/>
* </action-state>
* </pre>
*
* ... when entered, executes the method:
*
* <pre>
* public Event search(RequestContext context) throws Exception;
* </pre>
*
* Alternatively you may explictly specify the method name:
*
* <pre>
* <action-state id="searchState">
* <action bean="my.search.action" method="search"/>
* <transition on="success" to="results"/>
* </action-state>
* </pre>
*
* <p>
* A typical use of the MultiAction is to centralize all command logic for a flow
* in one place. Another common use is to centralize form setup and submit logic
* into one place, or CRUD (create/read/update/delete) operations for a single
* domain object in one place.
* <p>
* <b>Exposed configuration properties:</b> <br>
* <table border="1">
* <tr>
* <td><b>Name </b></td>
* <td><b>Default </b></td>
* <td><b>Description </b></td>
* </tr>
* <tr>
* <td>delegate</td>
* <td><i>this</i></td>
* <td>Set the delegate object holding the action execution methods.</td>
* </tr>
* <tr>
* <td>executeMethodNameResolver</td>
* <td><i>{@link MultiAction.DefaultActionExecuteMethodNameResolver default}</i></td>
* <td>Set the strategy used to resolve the name of an action execution method. Allows
* full control over the method resolution algorithm.</td>
* </tr>
* </table>
*
* @see MultiAction.ActionExecuteMethodNameResolver
* @see MultiAction.DefaultActionExecuteMethodNameResolver
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class MultiAction extends AbstractAction {
/**
* A cache for dispatched action execute methods.
*/
private DispatchMethodInvoker executeMethodDispatcher = new DispatchMethodInvoker(this,
new Class[] { RequestContext.class }, Event.class, "action");
/**
* The action execute method name resolver strategy.
*/
private ActionExecuteMethodNameResolver executeMethodNameResolver = new DefaultActionExecuteMethodNameResolver();
/**
* Returns the delegate object holding the action execution methods.
* Defaults to this object.
*/
public Object getDelegate() {
return this.executeMethodDispatcher.getTarget();
}
/**
* Set the delegate object holding the action execution methods.
* @param delegate the delegate to set
*/
public void setDelegate(Object delegate) {
this.executeMethodDispatcher.setTarget(delegate);
}
/**
* Get the strategy used to resolve action execution method names. Defaults
* to {@link MultiAction.DefaultActionExecuteMethodNameResolver}.
*/
public ActionExecuteMethodNameResolver getExecuteMethodNameResolver() {
return executeMethodNameResolver;
}
/**
* Set the strategy used to resolve action execution method names.
*/
public void setExecuteMethodNameResolver(ActionExecuteMethodNameResolver methodNameResolver) {
this.executeMethodNameResolver = methodNameResolver;
}
protected Event doExecute(RequestContext context) throws Exception {
String actionExecuteMethodName = this.executeMethodNameResolver.getMethodName(context);
return (Event)this.executeMethodDispatcher.dispatch(actionExecuteMethodName, new Object[] { context });
}
/**
* Strategy interface used by the MultiAction to map a request context to
* the name of an action execution method.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface ActionExecuteMethodNameResolver {
/**
* Resolve a method name from given flow execution request context.
* @param context the flow execution request context
* @return the name of the method that should handle action execution
*/
public String getMethodName(RequestContext context);
}
/**
* Default method name resolver used by the MultiAction class.
* It uses the following algorithm to calculate a method name:
* <ol>
* <li>If the currently executing action has a "method" property
* defined, use the value as method name.</li>
* <li>Else, use the name of the current state of the flow execution as a
* method name.</li>
* </ol>
*
* @author Erwin Vervaet
*/
public static class DefaultActionExecuteMethodNameResolver implements ActionExecuteMethodNameResolver {
/**
* Name of the property defining the execute method name.
*/
public static final String METHOD_PROPERTY = "method";
public String getMethodName(RequestContext context) {
AttributeSource properties = context.getProperties();
if (properties.containsAttribute(METHOD_PROPERTY)) {
// use specified execute method name
return (String)properties.getAttribute(METHOD_PROPERTY);
}
else {
// use current state name as method name
return context.getFlowExecutionContext().getCurrentState().getId();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -