KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > pageflow > UrlTag


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.bridge.jsp.taglib.pageflow;
11
12 import java.util.*;
13 import java.io.*;
14 import java.net.*;
15 import org.mmbase.bridge.jsp.taglib.*;
16 import org.mmbase.bridge.jsp.taglib.util.Attribute;
17 import org.mmbase.bridge.jsp.taglib.util.Referids;
18
19 import javax.servlet.jsp.JspTagException JavaDoc;
20 import javax.servlet.jsp.JspException JavaDoc;
21
22
23 import org.mmbase.util.transformers.Url;
24 import org.mmbase.util.transformers.CharTransformer;
25
26 import org.mmbase.util.Casting;
27 import org.mmbase.util.Entry;
28
29 import org.mmbase.util.logging.Logger;
30 import org.mmbase.util.logging.Logging;
31
32
33 /**
34  * A Tag to produce an URL with parameters. It can use 'context' parameters easily.
35  *
36  * @author Michiel Meeuwissen
37  * @version $Id: UrlTag.java,v 1.79.2.1 2006/11/15 19:49:30 michiel Exp $
38  */

39
40 public class UrlTag extends CloudReferrerTag implements ParamHandler {
41
42     private static final Logger log = Logging.getLoggerInstance(UrlTag.class);
43
44     private static final CharTransformer paramEscaper = new Url(Url.ESCAPE);
45
46     private static Boolean JavaDoc makeRelative = null;
47     private Attribute referids = Attribute.NULL;
48     protected final List extraParameters = new ArrayList();
49     protected Attribute page = Attribute.NULL;
50     protected Attribute escapeAmps = Attribute.NULL;
51     private Attribute absolute = Attribute.NULL;
52     protected Attribute encode = Attribute.NULL;
53
54     public void setReferids(String JavaDoc r) throws JspTagException JavaDoc {
55         referids = getAttribute(r);
56     }
57
58     public void setPage(String JavaDoc p) throws JspTagException JavaDoc {
59         page = getAttribute(p);
60     }
61
62     public void setEscapeamps(String JavaDoc e) throws JspTagException JavaDoc {
63         escapeAmps = getAttribute(e);
64     }
65
66     public void setEncode(String JavaDoc e) throws JspTagException JavaDoc {
67        encode = getAttribute(e);
68     }
69     
70     /**
71      * @since MMBase-1.8
72      */

73     public void setAbsolute(String JavaDoc a) throws JspTagException JavaDoc {
74         absolute = getAttribute(a);
75     }
76
77
78     public void addParameter(String JavaDoc key, Object JavaDoc value) throws JspTagException JavaDoc {
79         if (log.isDebugEnabled()) {
80             log.debug("adding parameter " + key + "/" + value);
81         }
82         extraParameters.add(new Entry(key, value));
83     }
84
85
86
87     public int doStartTag() throws JspTagException JavaDoc {
88         log.debug("starttag");
89         extraParameters.clear();
90         helper.useEscaper(false);
91         return EVAL_BODY_BUFFERED;
92     }
93
94
95     protected String JavaDoc getPage() throws JspTagException JavaDoc {
96         return page.getString(this);
97     }
98
99     /**
100      * If it would be nice that an URL starting with '/' would be generated relatively to the current request URL, then this method can do it.
101      * If the URL is not used to write to (this) page, then you probably don't want that.
102      *
103      * The behaviour can be overruled by starting the URL with two '/'s.
104      *
105      * @since MMBase-1.7
106      */

107     protected StringBuffer JavaDoc makeRelative(StringBuffer JavaDoc show) {
108         javax.servlet.http.HttpServletRequest JavaDoc req = (javax.servlet.http.HttpServletRequest JavaDoc)pageContext.getRequest();
109         if (show.charAt(0) == '/') { // absolute on servletcontex
110
if (show.length() > 1 && show.charAt(1) == '/') {
111                 log.debug("'absolute' url, not making relative");
112                 if (addContext()) {
113                     show.deleteCharAt(0);
114                     show.insert(0, req.getContextPath());
115                 }
116             } else {
117                 log.debug("'absolute' url");
118                 String JavaDoc thisDir = new java.io.File JavaDoc(req.getServletPath()).getParent();
119                 show.insert(0, org.mmbase.util.UriParser.makeRelative(thisDir, "/")); // makes a relative path to root.
120
}
121         }
122         return show;
123     }
124
125     /**
126      * Whether URL must be generatored relatively. This default to false, and can be configured with
127      * the servlet context init parameter 'mmbase.taglib.url.makerelative'. It can be useful to be
128      * sure that url's are relative, if e.g. the context path is taken away in an URL-rewrite (e.g. by proxy).
129      * This might give problems with redirects, but if you happen to solve that too, or don't do that...
130      *
131      * @since MMBase-1.7
132      */

133     protected boolean doMakeRelative() {
134         if (makeRelative == null) {
135             String JavaDoc setting = pageContext.getServletContext().getInitParameter("mmbase.taglib.url.makerelative");
136             makeRelative = "true".equals(setting) ? Boolean.TRUE : Boolean.FALSE;
137         }
138         return makeRelative.booleanValue();
139     }
140
141     protected boolean addContext() {
142         return true;
143     }
144
145     /**
146      * @since MMBase-1.8.1
147      */

148     protected boolean useAbsoluteAttribute(StringBuffer JavaDoc show, String JavaDoc page) throws JspTagException JavaDoc {
149         String JavaDoc abs = absolute.getString(this);
150         if ("".equals(abs) || "false".equals(abs)) return false;
151         javax.servlet.http.HttpServletRequest JavaDoc req = (javax.servlet.http.HttpServletRequest JavaDoc) pageContext.getRequest();
152
153         if (abs.equals("true")) {
154             String JavaDoc scheme = req.getScheme();
155             show.append(scheme).append("://");
156             show.append(req.getServerName());
157             int port = req.getServerPort();
158             show.append((port == 80 && "http".equals(scheme)) ||
159                         (port == 443 && "https".equals(scheme))
160                         ? "" : ":" + port);
161         } else if (abs.equals("server")) {
162             //show.append("/");
163
} else if (abs.equals("context")) {
164         } else {
165             throw new JspTagException JavaDoc("Unknown value for 'absolute' attribute '" + abs + "' (must be either 'true', 'false', 'server' or 'context')");
166         }
167         if (! abs.equals("context")) {
168             show.append(req.getContextPath());
169         }
170         char firstChar = page.charAt(0);
171         try {
172             URI uri;
173             if (firstChar != '/') {
174                 uri = new URI("servlet", req.getServletPath() + "/../" + page, null);
175             } else {
176                 uri = new URI("servlet", page, null);
177             }
178             uri = uri.normalize(); // resolves .. and so one
179
show.append(uri.getSchemeSpecificPart());
180         } catch (URISyntaxException use) {
181             throw new TaglibException(use.getMessage(), use);
182         }
183         return true;
184     }
185
186     /**
187      * Returns url with the extra parameters (of referids and sub-param-tags).
188      */

189     protected String JavaDoc getUrl(boolean writeamp, boolean encodeUrl) throws JspTagException JavaDoc {
190         StringWriter w = new StringWriter();
191         StringBuffer JavaDoc show = w.getBuffer();
192
193
194         if (referid != Attribute.NULL) {
195             if (page != Attribute.NULL) throw new TaglibException("Cannot specify both 'referid' and 'page' attributes");
196             String JavaDoc url = (String JavaDoc) getObject(getReferid());
197             if (writeamp) {
198                 url = url.replaceAll("&", "&");
199             }
200             if (! useAbsoluteAttribute(show, url)) {
201                 show.append(url);
202             }
203         } else {
204             String JavaDoc page = getPage();
205             javax.servlet.http.HttpServletRequest JavaDoc req = (javax.servlet.http.HttpServletRequest JavaDoc) pageContext.getRequest();
206             if (page.equals("")) { // means _this_ page
207
String JavaDoc requestURI = req.getRequestURI();
208                 if (requestURI.endsWith("/")) {
209                     page = ".";
210                 } else {
211                     page = new File(requestURI).getName();
212                 }
213
214             }
215             if (!useAbsoluteAttribute(show, page)) {
216                 if (doMakeRelative()) {
217                     show.append(page);
218                     page = "";
219                     makeRelative(show);
220                 } else {
221                     if (addContext() && page.charAt(0) == '/') { // absolute on servletcontex
222
show.append(req.getContextPath());
223                     }
224                 }
225                 show.append(page);
226             }
227
228         }
229
230
231         // url is now complete up to query string, which we are to construct now
232

233
234         String JavaDoc amp = (writeamp ? "&" : "&");
235         String JavaDoc connector = (show.toString().indexOf('?') == -1 ? "?" : amp);
236
237         if (referids != Attribute.NULL) {
238             Iterator refs = Referids.getReferids(referids, this).entrySet().iterator();
239             while (refs.hasNext()) {
240                 Map.Entry entry = (Map.Entry) refs.next();
241                 show.append(connector).append(entry.getKey()).append("=");
242                 paramEscaper.transform(new StringReader(Casting.toString(entry.getValue())), w);
243                 connector = amp;
244             }
245         }
246         Iterator i = extraParameters.iterator();
247         while (i.hasNext()) {
248             Entry param = (Entry) i.next();
249             if (param.getValue() == null) continue;
250             show.append(connector).append(param.getKey()).append('=');
251             paramEscaper.transform(new StringReader(Casting.toString(param.getValue())), w);
252             connector = amp;
253         }
254         if (encodeUrl) {
255             javax.servlet.http.HttpServletResponse JavaDoc response = (javax.servlet.http.HttpServletResponse JavaDoc)pageContext.getResponse();
256             return response.encodeURL(show.toString());
257         } else {
258             return show.toString();
259         }
260     }
261
262     protected String JavaDoc getUrl() throws JspTagException JavaDoc {
263         return getUrl(escapeAmps.getBoolean(this, true));
264     }
265
266     protected String JavaDoc getUrl(boolean e) throws JspTagException JavaDoc {
267         return getUrl(e, encode.getBoolean(this, true));
268     }
269
270     protected void doAfterBodySetValue() throws JspTagException JavaDoc {
271         helper.setValue(getUrl());
272     }
273
274     public int doAfterBody() throws JspException JavaDoc {
275         if (bodyContent != null) bodyContent.clearBody(); // don't show the body.
276
return helper.doAfterBody();
277     }
278
279
280     protected void initDoEndTag() throws JspTagException JavaDoc {
281         log.debug("endtag of url tag");
282         if (helper.getJspvar() == null) {
283             helper.overrideWrite(true);
284             // because Url tag can have subtags (param), default writing even with body seems sensible
285
// unless jspvar is specified, because then, perhaps the user wants that..
286
}
287
288     }
289     public int doEndTag() throws JspTagException JavaDoc {
290         if (getId() != null) {
291             getContextProvider().getContextContainer().register(getId(), getUrl(false, false)); // write it as cleanly as possible.
292
}
293         initDoEndTag();
294         doAfterBodySetValue();
295         helper.doEndTag();
296         extraParameters.clear();
297         return super.doEndTag();
298     }
299
300
301 }
302
Popular Tags