1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.components;
23
24 import java.io.Writer;
25 import java.util.Collections;
26 import java.util.Iterator;
27 import java.util.LinkedHashMap;
28 import java.util.Map;
29
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.struts2.StrutsConstants;
34 import org.apache.struts2.views.annotations.StrutsTag;
35 import org.apache.struts2.views.annotations.StrutsTagAttribute;
36 import org.apache.struts2.views.util.UrlHelper;
37
38 import com.opensymphony.xwork2.inject.Inject;
39 import com.opensymphony.xwork2.util.ValueStack;
40 import com.opensymphony.xwork2.util.logging.Logger;
41 import com.opensymphony.xwork2.util.logging.LoggerFactory;
42
43 /***
44 * <!-- START SNIPPET: javadoc -->
45 *
46 * <p>This tag is used to create a URL.</p>
47 *
48 * <p>You can use the <param> tag inside the body to provide
49 * additional request parameters. If the value of a param is an Array or
50 * an Iterable all the values will be added to the URL.</p>
51 *
52 * <b>NOTE:</b>
53 * <p>By default request parameters will be separated using escaped ampersands (i.e., &amp;).
54 * This is necessary for XHTML compliance, however, when using the URL generated by this tag
55 * with the <s:property> tag, the <b>escapeAmp</b> attribute should be used to disable
56 * ampersand escaping.</p>
57 *
58 * <b>NOTE:</b>
59 * <p>When includeParams is 'all' or 'get', the parameter defined in a <param>
60 * tag will take precedence over any params included due to the includeParams attribute. For
61 * example, in Example 3 below, if there is a id parameter in the url where the page this
62 * tag is included like http://<host>:<port>/<context>/editUser.action?id=3333&name=John
63 * the generated url will be http://<host>:<port>/<context>/editUser.action?id=22&name=John
64 * because the parameter defined in the param tag will take precedence.</p>
65 *
66 * <!-- END SNIPPET: javadoc -->
67 *
68 *
69 * <!-- START SNIPPET: params -->
70 *
71 * <ul>
72 * <li>action (String) - (value or action choose either one, if both exist value takes precedence) action's name (alias) <li>
73 * <li>value (String) - (value or action choose either one, if both exist value takes precedence) the url itself</li>
74 * <li>scheme (String) - http scheme (http, https) defaults to the scheme this request is in</li>
75 * <li>namespace - action's namespace</li>
76 * <li>method (String) - action's method name, defaults to 'execute'</li>
77 * <li>encode (Boolean) - url encode the generated url. Defaults to 'true'.</li>
78 * <li>includeParams (String) - The includeParams attribute may have the value 'none', 'get' or 'all'. Defaults to 'get'.
79 * none - include no parameters in the URL
80 * get - include only GET parameters in the URL (default)
81 * all - include both GET and POST parameters in the URL
82 * </li>
83 * <li>includeContext (Boolean) - Specifies whether to include the web app context path. Defaults to 'true'.</li>
84 * <li>escapeAmp (Boolean) - Specifies whether to escape ampersand (&) to (&amp;) or not. Defaults to 'true'.</li>
85 * <li>portletMode (String) - The resulting portlet mode.</li>
86 * <li>windowState (String) - The resulting portlet window state.</li>
87 * <li>portletUrlType (String) - Specifies if this should be a portlet render or action URL.</li>
88 * <li>forceAddSchemeHostAndPort (Boolean) - Specifies whether to force the addition of scheme, host and port or not.</li>
89 * </ul>
90 *
91 * <!-- END SNIPPET: params -->
92 *
93 * <p/> <b>Examples</b>
94 * <pre>
95 * <!-- START SNIPPET: example -->
96 *
97 * <-- Example 1 -->
98 * <s:url value="editGadget.action">
99 * <s:param name="id" value="%{selected}" />
100 * </s:url>
101 *
102 * <-- Example 2 -->
103 * <s:url action="editGadget">
104 * <s:param name="id" value="%{selected}" />
105 * </s:url>
106 *
107 * <-- Example 3-->
108 * <s:url includeParams="get">
109 * <s:param name="id" value="%{'22'}" />
110 * </s:url>
111 *
112 * <!-- END SNIPPET: example -->
113 * </pre>
114 *
115 * @see Param
116 *
117 */
118 @StrutsTag(name="url", tldTagClass="org.apache.struts2.views.jsp.URLTag", description="This tag is used to create a URL")
119 public class URL extends ContextBean {
120 private static final Logger LOG = LoggerFactory.getLogger(URL.class);
121
122 /***
123 * The includeParams attribute may have the value 'none', 'get' or 'all'.
124 * It is used when the url tag is used without a value attribute.
125 * Its value is looked up on the ValueStack
126 * If no includeParams is specified then 'get' is used.
127 * none - include no parameters in the URL
128 * get - include only GET parameters in the URL (default)
129 * all - include both GET and POST parameters in the URL
130 */
131 public static final String NONE = "none";
132 public static final String GET = "get";
133 public static final String ALL = "all";
134
135 protected HttpServletRequest req;
136 protected HttpServletResponse res;
137
138 protected String includeParams;
139 protected String scheme;
140 protected String value;
141 protected String action;
142 protected String namespace;
143 protected String method;
144 protected boolean encode = true;
145 protected boolean includeContext = true;
146 protected boolean escapeAmp = true;
147 protected String portletMode;
148 protected String windowState;
149 protected String portletUrlType;
150 protected String anchor;
151 protected boolean forceAddSchemeHostAndPort;
152 protected String urlIncludeParams;
153 protected ExtraParameterProvider extraParameterProvider;
154 protected UrlRenderer urlRenderer;
155
156 public URL(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
157 super(stack);
158 this.req = req;
159 this.res = res;
160 }
161
162 @Inject(StrutsConstants.STRUTS_URL_INCLUDEPARAMS)
163 public void setUrlIncludeParams(String urlIncludeParams) {
164 this.urlIncludeParams = urlIncludeParams;
165 }
166
167 @Inject
168 public void setUrlRenderer(UrlRenderer urlRenderer) {
169 this.urlRenderer = urlRenderer;
170 }
171
172 @Inject(required=false)
173 public void setExtraParameterProvider(ExtraParameterProvider provider) {
174 this.extraParameterProvider = provider;
175 }
176
177 public boolean start(Writer writer) {
178 boolean result = super.start(writer);
179 urlRenderer.beforeRenderUrl(this);
180 return result;
181 }
182
183 public boolean end(Writer writer, String body) {
184 urlRenderer.renderUrl(writer, this);
185 return super.end(writer, body);
186 }
187
188 @StrutsTagAttribute(description="The includeParams attribute may have the value 'none', 'get' or 'all'", defaultValue="none")
189 public void setIncludeParams(String includeParams) {
190 this.includeParams = includeParams;
191 }
192
193 @StrutsTagAttribute(description="Set scheme attribute")
194 public void setScheme(String scheme) {
195 this.scheme = scheme;
196 }
197
198 @StrutsTagAttribute(description="The target value to use, if not using action")
199 public void setValue(String value) {
200 this.value = value;
201 }
202
203 @StrutsTagAttribute(description="The action to generate the URL for, if not using value")
204 public void setAction(String action) {
205 this.action = action;
206 }
207
208 @StrutsTagAttribute(description="The namespace to use")
209 public void setNamespace(String namespace) {
210 this.namespace = namespace;
211 }
212
213 @StrutsTagAttribute(description="The method of action to use")
214 public void setMethod(String method) {
215 this.method = method;
216 }
217
218 @StrutsTagAttribute(description="Whether to encode parameters", type="Boolean", defaultValue="true")
219 public void setEncode(boolean encode) {
220 this.encode = encode;
221 }
222
223 @StrutsTagAttribute(description="Whether actual context should be included in URL", type="Boolean", defaultValue="true")
224 public void setIncludeContext(boolean includeContext) {
225 this.includeContext = includeContext;
226 }
227
228 @StrutsTagAttribute(description="The resulting portlet mode")
229 public void setPortletMode(String portletMode) {
230 this.portletMode = portletMode;
231 }
232
233 @StrutsTagAttribute(description="The resulting portlet window state")
234 public void setWindowState(String windowState) {
235 this.windowState = windowState;
236 }
237
238 @StrutsTagAttribute(description="Specifies if this should be a portlet render or action URL. Default is \"render\". To create an action URL, use \"action\".")
239 public void setPortletUrlType(String portletUrlType) {
240 this.portletUrlType = portletUrlType;
241 }
242
243 @StrutsTagAttribute(description="The anchor for this URL")
244 public void setAnchor(String anchor) {
245 this.anchor = anchor;
246 }
247
248 @StrutsTagAttribute(description="Specifies whether to escape ampersand (&) to (&amp;) or not", type="Boolean", defaultValue="true")
249 public void setEscapeAmp(boolean escapeAmp) {
250 this.escapeAmp = escapeAmp;
251 }
252
253 @StrutsTagAttribute(description="Specifies whether to force the addition of scheme, host and port or not", type="Boolean", defaultValue="false")
254 public void setForceAddSchemeHostAndPort(boolean forceAddSchemeHostAndPort) {
255 this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
256 }
257
258 public static interface ExtraParameterProvider {
259 public Map getExtraParameters();
260 }
261 }