KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > action > MultiAction


1 /*
2  * Copyright 2002-2006 the original author or authors.
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 package org.springframework.webflow.action;
17
18 import org.springframework.util.Assert;
19 import org.springframework.webflow.execution.Event;
20 import org.springframework.webflow.execution.RequestContext;
21 import org.springframework.webflow.util.DispatchMethodInvoker;
22
23 /**
24  * Action implementation that bundles two or more action execution methods into
25  * a single class. Action execution methods defined by subclasses must adhere to
26  * the following signature:
27  *
28  * <pre>
29  * public Event ${method}(RequestContext context) throws Exception;
30  * </pre>
31  *
32  * When this action is invoked, by default the <code>id</code> of the calling
33  * action state state is treated as the action execution method name.
34  * Alternatively, the execution method name may be explicitly specified as a
35  * attribute of the calling action state.
36  * <p>
37  * For example, the following action state definition:
38  *
39  * <pre>
40  * &lt;action-state id=&quot;search&quot;&gt;
41  * &lt;action bean=&quot;searchAction&quot;/&gt;
42  * &lt;transition on=&quot;success&quot; to=&quot;results&quot;/&gt;
43  * &lt;/action-state&gt;
44  * </pre>
45  *
46  * ... when entered, executes the method:
47  *
48  * <pre>
49  * public Event search(RequestContext context) throws Exception;
50  * </pre>
51  *
52  * Alternatively (and typically recommended), you may explictly specify the method name:
53  *
54  * <pre>
55  * &lt;action-state id=&quot;search&quot;&gt;
56  * &lt;action bean=&quot;searchAction&quot; method=&quot;executeSearch&quot;/&gt;
57  * &lt;transition on=&quot;success&quot; to=&quot;results&quot;/&gt;
58  * &lt;/action-state&gt;
59  * </pre>
60  *
61  * <p>
62  * A typical use of the MultiAction is to centralize all command logic for a
63  * flow in one place. Another common use is to centralize form setup and submit
64  * logic in one place, or CRUD (create/read/update/delete) operations for a
65  * single domain object in one place.
66  *
67  * @see MultiAction.MethodResolver
68  * @see org.springframework.webflow.action.DefaultMultiActionMethodResolver
69  *
70  * @author Keith Donald
71  * @author Erwin Vervaet
72  */

73 public class MultiAction extends AbstractAction {
74
75     /**
76      * A cache for dispatched action execute methods. The default signature is
77      * <code>public Event ${method}(RequestContext context) throws Exception;</code>.
78      */

79     private DispatchMethodInvoker methodInvoker;
80
81     /**
82      * The action method resolver strategy.
83      */

84     private MethodResolver methodResolver = new DefaultMultiActionMethodResolver();
85
86     /**
87      * Protected default constructor; not invokable for direct MultiAction instantiation.
88      * Intended for use by subclasses.
89      * <p>
90      * Sets the target to this multi action instance.
91      * @see #setTarget(Object)
92      */

93     protected MultiAction() {
94         setTarget(this);
95     }
96
97     /**
98      * Constructs a multi action that invokes methods on the specified target
99      * object. Note: invokable methods on the target must conform to the multi action
100      * method signature:
101      * <pre>
102      * public Event ${method}(RequestContext context) throws Exception;
103      * </pre>
104      * @param target the target of this multi action's invocations
105      */

106     public MultiAction(Object JavaDoc target) {
107         setTarget(target);
108     }
109
110     /**
111      * Sets the target of this multi action's invocations.
112      * @param target the target
113      */

114     protected final void setTarget(Object JavaDoc target) {
115         methodInvoker = new DispatchMethodInvoker(target, new Class JavaDoc[] { RequestContext.class } );
116     }
117
118     /**
119      * Get the strategy used to resolve action execution method names.
120      */

121     public MethodResolver getMethodResolver() {
122         return methodResolver;
123     }
124
125     /**
126      * Set the strategy used to resolve action execution method names.
127      * Allows full control over the method resolution algorithm.
128      * Defaults to {@link DefaultMultiActionMethodResolver}.
129      */

130     public void setMethodResolver(MethodResolver methodResolver) {
131         this.methodResolver = methodResolver;
132     }
133
134     protected final Event doExecute(RequestContext context) throws Exception JavaDoc {
135         String JavaDoc method = getMethodResolver().resolveMethod(context);
136         Object JavaDoc obj = methodInvoker.invoke(method, new Object JavaDoc[] { context });
137         if (obj != null) {
138             Assert.isInstanceOf(Event.class, obj,
139                     "The '" + method + "' action execution method on target object '" +
140                     methodInvoker.getTarget() + "' did not return an Event object but '" +
141                     obj + "' of type " + obj.getClass().getName() + " -- " +
142                     "Programmer error; make sure the method signature conforms to " +
143                     "'public Event ${method}(RequestContext context) throws Exception;'.");
144         }
145         return (Event)obj;
146     }
147
148     /**
149      * Strategy interface used by the MultiAction to map a request context to
150      * the name of an action execution method.
151      *
152      * @author Keith Donald
153      * @author Erwin Vervaet
154      */

155     public interface MethodResolver {
156
157         /**
158          * Resolve a method name from given flow execution request context.
159          * @param context the flow execution request context
160          * @return the name of the method that should handle action
161          * execution
162          */

163         public String JavaDoc resolveMethod(RequestContext context);
164     }
165 }
Popular Tags