1 /*
2 * Copyright (c) 2002-2006 by OpenSymphony
3 * All rights reserved.
4 */
5
6 package com.opensymphony.xwork2.interceptor;
7
8 import java.util.Iterator;
9 import java.util.Map;
10
11 import com.opensymphony.xwork2.ActionContext;
12 import com.opensymphony.xwork2.ActionInvocation;
13 import com.opensymphony.xwork2.config.entities.ActionConfig;
14 import com.opensymphony.xwork2.util.ValueStack;
15 import com.opensymphony.xwork2.util.logging.Logger;
16 import com.opensymphony.xwork2.util.logging.LoggerFactory;
17
18
19 /**
20 * <!-- START SNIPPET: description -->
21 *
22 * The aim of this Interceptor is to alias a named parameter to a different named parameter. By acting as the glue
23 * between actions sharing similiar parameters (but with different names), it can help greatly with action chaining.
24 *
25 * <p/> Action's alias expressions should be in the form of <code>#{ "name1" : "alias1", "name2" : "alias2" }</code>.
26 * This means that assuming an action (or something else in the stack) has a value for the expression named <i>name1</i> and the
27 * action this interceptor is applied to has a setter named <i>alias1</i>, <i>alias1</i> will be set with the value from
28 * <i>name1</i>.
29 *
30 * <!-- END SNIPPET: description -->
31 *
32 * <p/> <u>Interceptor parameters:</u>
33 *
34 * <!-- START SNIPPET: parameters -->
35 *
36 * <ul>
37 *
38 * <li>aliasesKey (optional) - the name of the action parameter to look for the alias map (by default this is
39 * <i>aliases</i>).</li>
40 *
41 * </ul>
42 *
43 * <!-- END SNIPPET: parameters -->
44 *
45 * <p/> <u>Extending the interceptor:</u>
46 *
47 * <p/>
48 *
49 * <!-- START SNIPPET: extending -->
50 *
51 * This interceptor does not have any known extension points.
52 *
53 * <!-- END SNIPPET: extending -->
54 *
55 * <p/> <u>Example code:</u>
56 *
57 * <pre>
58 * <!-- START SNIPPET: example -->
59 * <action name="someAction" class="com.examples.SomeAction">
60 * <!-- The value for the foo parameter will be applied as if it were named bar -->
61 * <param name="aliases">#{ 'foo' : 'bar' }</param>
62 *
63 * <interceptor-ref name="alias"/>
64 * <interceptor-ref name="basicStack"/>
65 * <result name="success">good_result.ftl</result>
66 * </action>
67 * <!-- END SNIPPET: example -->
68 * </pre>
69 *
70 * @author Matthew Payne
71 */
72 public class AliasInterceptor extends AbstractInterceptor {
73
74 private static final Logger log = LoggerFactory.getLogger(AliasInterceptor.class);
75
76 private static final String DEFAULT_ALIAS_KEY = "aliases";
77 protected String aliasesKey = DEFAULT_ALIAS_KEY;
78
79 /**
80 * Sets the name of the action parameter to look for the alias map.
81 * <p/>
82 * Default is <code>aliases</code>.
83 *
84 * @param aliasesKey the name of the action parameter
85 */
86 public void setAliasesKey(String aliasesKey) {
87 this.aliasesKey = aliasesKey;
88 }
89
90 public String intercept(ActionInvocation invocation) throws Exception {
91
92 ActionConfig config = invocation.getProxy().getConfig();
93 ActionContext ac = invocation.getInvocationContext();
94
95 // get the action's parameters
96 final Map parameters = config.getParams();
97
98 if (parameters.containsKey(aliasesKey)) {
99
100 String aliasExpression = (String) parameters.get(aliasesKey);
101 ValueStack stack = ac.getValueStack();
102 Object obj = stack.findValue(aliasExpression);
103
104 if (obj != null && obj instanceof Map) {
105 // override
106 Map aliases = (Map) obj;
107 Iterator itr = aliases.entrySet().iterator();
108 while (itr.hasNext()) {
109 Map.Entry entry = (Map.Entry) itr.next();
110 String name = entry.getKey().toString();
111 String alias = (String) entry.getValue();
112 Object value = stack.findValue(name);
113 if (null == value) {
114 // workaround
115 Map contextParameters = (Map) stack.getContext().get("parameters");
116
117 if (null != contextParameters) {
118 value = contextParameters.get(name);
119 }
120 }
121 if (null != value) {
122 stack.setValue(alias, value);
123 }
124 }
125 } else {
126 log.debug("invalid alias expression:" + aliasesKey);
127 }
128 }
129
130 return invocation.invoke();
131 }
132
133 }