|
18 | 18 | */
|
19 | 19 | package com.opensymphony.xwork2;
|
20 | 20 |
|
21 |
| -import com.opensymphony.xwork2.inject.Inject; |
22 |
| -import com.opensymphony.xwork2.util.TextParseUtil; |
23 |
| -import org.apache.logging.log4j.LogManager; |
24 |
| -import org.apache.logging.log4j.Logger; |
25 |
| -import org.apache.struts2.StrutsException; |
26 |
| - |
27 |
| -import java.util.HashMap; |
28 |
| -import java.util.HashSet; |
29 |
| -import java.util.LinkedList; |
30 |
| -import java.util.List; |
31 |
| -import java.util.Map; |
32 |
| -import java.util.Objects; |
33 |
| -import java.util.Set; |
34 |
| - |
35 | 21 | /**
|
36 |
| -* <!-- START SNIPPET: description --> |
37 |
| -* |
38 |
| -* This result invokes an entire other action, complete with it's own interceptor stack and result. |
39 |
| -* |
40 |
| -* <!-- END SNIPPET: description --> |
41 |
| -* |
42 |
| -* <b>This result type takes the following parameters:</b> |
43 |
| -* |
44 |
| -* <!-- START SNIPPET: params --> |
45 |
| -* |
46 |
| -* <ul> |
47 |
| -* |
48 |
| -* <li><b>actionName (default)</b> - the name of the action that will be chained to</li> |
49 |
| -* |
50 |
| -* <li><b>namespace</b> - used to determine which namespace the Action is in that we're chaining. If namespace is null, |
51 |
| -* this defaults to the current namespace</li> |
52 |
| -* |
53 |
| -* <li><b>method</b> - used to specify another method on target action to be invoked. |
54 |
| -* If null, this defaults to execute method</li> |
55 |
| -* |
56 |
| -* <li><b>skipActions</b> - (optional) the list of comma separated action names for the |
57 |
| -* actions that could be chained to</li> |
58 |
| -* |
59 |
| -* </ul> |
60 |
| -* |
61 |
| -* <!-- END SNIPPET: params --> |
62 |
| -* |
63 |
| -* <b>Example:</b> |
64 |
| -* |
65 |
| -* <pre><!-- START SNIPPET: example --> |
66 |
| -* <package name="public" extends="struts-default"> |
67 |
| -* <!-- Chain creatAccount to login, using the default parameter --> |
68 |
| -* <action name="createAccount" class="..."> |
69 |
| -* <result type="chain">login</result> |
70 |
| -* </action> |
71 |
| -* |
72 |
| -* <action name="login" class="..."> |
73 |
| -* <!-- Chain to another namespace --> |
74 |
| -* <result type="chain"> |
75 |
| -* <param name="actionName">dashboard</param> |
76 |
| -* <param name="namespace">/secure</param> |
77 |
| -* </result> |
78 |
| -* </action> |
79 |
| -* </package> |
80 |
| -* |
81 |
| -* <package name="secure" extends="struts-default" namespace="/secure"> |
82 |
| -* <action name="dashboard" class="..."> |
83 |
| -* <result>dashboard.jsp</result> |
84 |
| -* </action> |
85 |
| -* </package> |
86 |
| -* <!-- END SNIPPET: example --></pre> |
87 |
| -* |
88 |
| -* @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a> |
89 |
| -*/ |
90 |
| -public class ActionChainResult implements Result { |
91 |
| - |
92 |
| - private static final Logger LOG = LogManager.getLogger(ActionChainResult.class); |
93 |
| - |
94 |
| - /** |
95 |
| - * The result parameter name to set the name of the action to chain to. |
96 |
| - */ |
97 |
| - public static final String DEFAULT_PARAM = "actionName"; |
98 |
| - |
99 |
| - /** |
100 |
| - * The action context key to save the chain history. |
101 |
| - */ |
102 |
| - private static final String CHAIN_HISTORY = "CHAIN_HISTORY"; |
103 |
| - |
104 |
| - private ActionProxy proxy; |
105 |
| - private String actionName; |
106 |
| - |
107 |
| - private String namespace; |
108 |
| - |
109 |
| - private String methodName; |
110 |
| - |
111 |
| - /** |
112 |
| - * The list of actions to skip. |
113 |
| - */ |
114 |
| - private String skipActions; |
115 |
| - |
116 |
| - private ActionProxyFactory actionProxyFactory; |
117 |
| - |
118 |
| - public ActionChainResult() { |
119 |
| - super(); |
120 |
| - } |
121 |
| - |
122 |
| - public ActionChainResult(String namespace, String actionName, String methodName) { |
123 |
| - this.namespace = namespace; |
124 |
| - this.actionName = actionName; |
125 |
| - this.methodName = methodName; |
126 |
| - } |
127 |
| - |
128 |
| - public ActionChainResult(String namespace, String actionName, String methodName, String skipActions) { |
129 |
| - this.namespace = namespace; |
130 |
| - this.actionName = actionName; |
131 |
| - this.methodName = methodName; |
132 |
| - this.skipActions = skipActions; |
133 |
| - } |
134 |
| - |
135 |
| - /** |
136 |
| - * @param actionProxyFactory the actionProxyFactory to set |
137 |
| - */ |
138 |
| - @Inject |
139 |
| - public void setActionProxyFactory(ActionProxyFactory actionProxyFactory) { |
140 |
| - this.actionProxyFactory = actionProxyFactory; |
141 |
| - } |
142 |
| - |
143 |
| - /** |
144 |
| - * Set the action name. |
145 |
| - * |
146 |
| - * @param actionName The action name. |
147 |
| - */ |
148 |
| - public void setActionName(String actionName) { |
149 |
| - this.actionName = actionName; |
150 |
| - } |
151 |
| - |
152 |
| - /** |
153 |
| - * sets the namespace of the Action that we're chaining to. if namespace |
154 |
| - * is null, this defaults to the current namespace. |
155 |
| - * |
156 |
| - * @param namespace the name of the namespace we're chaining to |
157 |
| - */ |
158 |
| - public void setNamespace(String namespace) { |
159 |
| - this.namespace = namespace; |
160 |
| - } |
161 |
| - |
162 |
| - /** |
163 |
| - * Set the list of actions to skip. |
164 |
| - * To test if an action should not throe an infinite recursion, |
165 |
| - * only the action name is used, not the namespace. |
166 |
| - * |
167 |
| - * @param actions The list of action name separated by a white space. |
168 |
| - */ |
169 |
| - public void setSkipActions(String actions) { |
170 |
| - this.skipActions = actions; |
171 |
| - } |
172 |
| - |
173 |
| - public void setMethod(String method) { |
174 |
| - this.methodName = method; |
175 |
| - } |
176 |
| - |
177 |
| - public ActionProxy getProxy() { |
178 |
| - return proxy; |
179 |
| - } |
180 |
| - |
181 |
| - /** |
182 |
| - * Get the XWork chain history. |
183 |
| - * The stack is a list of <code>namespace/action!method</code> keys. |
184 |
| - * |
185 |
| - * @return the chain history as string list |
186 |
| - */ |
187 |
| - public static LinkedList<String> getChainHistory() { |
188 |
| - LinkedList<String> chainHistory = (LinkedList<String>) ActionContext.getContext().get(CHAIN_HISTORY); |
189 |
| - // Add if not exists |
190 |
| - if (chainHistory == null) { |
191 |
| - chainHistory = new LinkedList<>(); |
192 |
| - ActionContext.getContext().put(CHAIN_HISTORY, chainHistory); |
193 |
| - } |
194 |
| - |
195 |
| - return chainHistory; |
196 |
| - } |
197 |
| - |
198 |
| - /** |
199 |
| - * @param invocation the DefaultActionInvocation calling the action call stack |
200 |
| - */ |
201 |
| - public void execute(ActionInvocation invocation) throws Exception { |
202 |
| - if (invocation == null) { |
203 |
| - throw new IllegalArgumentException("Invocation cannot be null!"); |
204 |
| - } |
205 |
| - |
206 |
| - String finalNamespace = namespace != null ? translateVariables(namespace) : invocation.getProxy() |
207 |
| - .getNamespace(); |
208 |
| - String finalActionName = translateVariables(actionName); |
209 |
| - String finalMethodName = methodName != null ? translateVariables(methodName) : null; |
210 |
| - |
211 |
| - if (isInChainHistory(finalNamespace, finalActionName, finalMethodName)) { |
212 |
| - addToHistory(finalNamespace, finalActionName, finalMethodName); |
213 |
| - throw new StrutsException("Infinite recursion detected: " + ActionChainResult.getChainHistory()); |
214 |
| - } |
215 |
| - |
216 |
| - if (ActionChainResult.getChainHistory().isEmpty() && invocation.getProxy() != null) { |
217 |
| - addToHistory(finalNamespace, invocation.getProxy().getActionName(), invocation.getProxy().getMethod()); |
218 |
| - } |
219 |
| - addToHistory(finalNamespace, finalActionName, finalMethodName); |
220 |
| - |
221 |
| - Map<String, Object> extraContext = ActionContext.of() |
222 |
| - .withValueStack(invocation.getInvocationContext().getValueStack()) |
223 |
| - .withParameters(invocation.getInvocationContext().getParameters()) |
224 |
| - .with(CHAIN_HISTORY, ActionChainResult.getChainHistory()) |
225 |
| - .getContextMap(); |
226 |
| - |
227 |
| - LOG.debug("Chaining to action {}", finalActionName); |
228 |
| - |
229 |
| - proxy = actionProxyFactory.createActionProxy(finalNamespace, finalActionName, finalMethodName, extraContext); |
230 |
| - proxy.execute(); |
231 |
| - } |
232 |
| - |
233 |
| - protected String translateVariables(String text) { |
234 |
| - return TextParseUtil.translateVariables(text, ActionContext.getContext().getValueStack()); |
235 |
| - } |
236 |
| - |
237 |
| - @Override |
238 |
| - public boolean equals(Object o) { |
239 |
| - if (this == o) { |
240 |
| - return true; |
241 |
| - } |
242 |
| - if (o == null || getClass() != o.getClass()) { |
243 |
| - return false; |
244 |
| - } |
245 |
| - ActionChainResult that = (ActionChainResult) o; |
246 |
| - return Objects.equals(actionName, that.actionName) && Objects.equals(methodName, |
247 |
| - that.methodName) && Objects.equals(namespace, that.namespace); |
248 |
| - } |
249 |
| - |
250 |
| - @Override |
251 |
| - public int hashCode() { |
252 |
| - int result; |
253 |
| - result = (actionName != null ? actionName.hashCode() : 0); |
254 |
| - result = 31 * result + (namespace != null ? namespace.hashCode() : 0); |
255 |
| - result = 31 * result + (methodName != null ? methodName.hashCode() : 0); |
256 |
| - return result; |
257 |
| - } |
258 |
| - |
259 |
| - private boolean isInChainHistory(String namespace, String actionName, String methodName) { |
260 |
| - LinkedList<? extends String> chainHistory = ActionChainResult.getChainHistory(); |
261 |
| - Set<String> skipActionsList = new HashSet<>(); |
262 |
| - if (skipActions != null && skipActions.length() > 0) { |
263 |
| - String finalSkipActions = translateVariables(skipActions); |
264 |
| - skipActionsList.addAll(TextParseUtil.commaDelimitedStringToSet(finalSkipActions)); |
265 |
| - } |
266 |
| - if (!skipActionsList.contains(actionName)) { |
267 |
| - return chainHistory.contains(makeKey(namespace, actionName, methodName)); |
268 |
| - } |
269 |
| - return false; |
270 |
| - } |
271 |
| - |
272 |
| - private void addToHistory(String namespace, String actionName, String methodName) { |
273 |
| - List<String> chainHistory = ActionChainResult.getChainHistory(); |
274 |
| - chainHistory.add(makeKey(namespace, actionName, methodName)); |
275 |
| - } |
276 |
| - |
277 |
| - private String makeKey(String namespace, String actionName, String methodName) { |
278 |
| - return namespace + "/" + actionName + (methodName != null ? "!" + methodName : ""); |
279 |
| - } |
| 22 | + * @deprecated since 6.7.0, use {@link org.apache.struts2.result.ActionChainResult} instead. |
| 23 | + */ |
| 24 | +@Deprecated |
| 25 | +public class ActionChainResult extends org.apache.struts2.result.ActionChainResult { |
280 | 26 | }
|
0 commit comments