View Javadoc

1   /*
2    * $Id: URL.java 722331 2008-12-02 02:04:42Z davenewton $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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 &lt;param&gt; 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;amp;).
54   * This is necessary for XHTML compliance, however, when using the URL generated by this tag
55   * with the &lt;s:property&gt; 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 &lt;param&gt;
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://&lt;host&gt;:&lt;port&gt;/&lt;context&gt;/editUser.action?id=3333&name=John
63   * the generated url will be http://&lt;host&gt;:&lt;port&gt;/&lt;context&gt;/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 (&amp;) to (&amp;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   * &lt;-- Example 1 --&gt;
98   * &lt;s:url value="editGadget.action"&gt;
99   *     &lt;s:param name="id" value="%{selected}" /&gt;
100  * &lt;/s:url&gt;
101  *
102  * &lt;-- Example 2 --&gt;
103  * &lt;s:url action="editGadget"&gt;
104  *     &lt;s:param name="id" value="%{selected}" /&gt;
105  * &lt;/s:url&gt;
106  *
107  * &lt;-- Example 3--&gt;
108  * &lt;s:url includeParams="get"&gt;
109  *     &lt;s:param name="id" value="%{'22'}" /&gt;
110  * &lt;/s:url&gt;
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 (&amp;) to (&amp;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 }