Proposal for URL tag -------------------- Key: STS-187 URL: http://mc4j.org/jira/browse/STS-187 Project: Stripes Type: New Feature
Components: Tag Library Versions: Release 1.3 Reporter: Mark Eagle Assigned to: Tim Fennell Priority: Minor I would like your thoughts on creating a <stripes:url> tag to allow users to generate Stripes urls. I created a UrlTag and UrlParamTag that mimics the functionality of LinkTag and LinkParamTag respectively as a short term solution. The only real differences are that UrlTag does not have all of the attributes of UrlTag and the <a> tags are not generated. Here are the tags and configuration: UrlTag.java ------------------------------------------------------------------------------ package net.sourceforge.stripes.tag; import net.sourceforge.stripes.exception.StripesJspException; import net.sourceforge.stripes.util.UrlBuilder; import net.sourceforge.stripes.controller.StripesConstants; import net.sourceforge.stripes.tag.HtmlTagSupport; import javax.servlet.jsp.tagext.BodyTag; import javax.servlet.jsp.JspException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.HashMap; import java.io.IOException; /** * Tag for generating URL links to pages or ActionBeans within a Stripes application. Provides * basic services such as including the context path at the start of the URL (only * when the URL starts with a '/' and does not contain the context path already), and * including a parameter to name the source page from which the link came. Also provides the * ability to add complex parameters to the URL through the use of nested LinkParam tags. * * @see UrlParamTag * @author Mark Eagle */ public class UrlTag extends HtmlTagSupport implements BodyTag { private Map<String,Object> parameters = new HashMap<String,Object>(); private String event; private Object beanclass; /** * Used by stripes:link-param tags (and possibly other tags at some distant point in * the future) to add a parameter to the parent link tag. * * @param name the name of the parameter(s) to add * @param valueOrValues */ public void addParameter(String name, Object valueOrValues) { this.parameters.put(name, valueOrValues); } /** Retrieves the parameter values set on the tag. */ public Map<String,Object> getParameters() { return this.parameters; } /** * Does nothing. * @return EVAL_BODY_BUFFERED in all cases */ public int doStartTag() throws JspException { return EVAL_BODY_BUFFERED; } /** Does nothing. */ public void doInitBody() throws JspException { /* Do Nothing. */ } /** * Does nothing. * @return SKIP_BODY in all cases */ public int doAfterBody() throws JspException { return SKIP_BODY; } /** * Prepends the context to the href attibute if necessary, and then folds all the * registered parameters into the URL. * * @return EVAL_PAGE in all cases * @throws javax.servlet.jsp.JspException */ public int doEndTag() throws JspException { // If the beanclass attribute was supplied we'll prefer that to an href if (this.beanclass != null) { String beanURL = getActionBeanUrl(beanclass); if (beanURL == null) { throw new StripesJspException("The value supplied for the 'beanclass' attribute " + "does not represent a valid ActionBean. The value supplied was '" + this.beanclass + "'. If you're prototyping, or your bean isn't ready yet " + "and you want this exception to go away, just use 'href' for now instead."); } else { setUrl(beanURL); } } HttpServletRequest request = (HttpServletRequest) getPageContext().getRequest(); HttpServletResponse response = (HttpServletResponse) getPageContext().getResponse(); String originalURL = getUrl(); // Save for later, so we can restore the value if (originalURL != null) { String url = originalURL; String contextPath = request.getContextPath(); // Append the context path, but only if the user didn't already if (originalURL.startsWith("/") && !"/".equals(contextPath) && !originalURL.contains(contextPath + "/")) { url = contextPath + url; } // Add all the parameters and reset the href attribute; pass to false here because // the HtmlTagSupport will HtmlEncode the ampersands for us UrlBuilder builder = new UrlBuilder(url, false); if (this.event != null) { builder.addParameter(this.event); } builder.addParameter(StripesConstants.URL_KEY_SOURCE_PAGE, request.getServletPath()); builder.addParameters(this.parameters); setUrl(response.encodeURL(builder.toString())); } try { getPageContext().getOut().write(getUrl().trim()); String body = getBodyContentAsString(); if (body != null) { getPageContext().getOut().write(body.trim()); } } catch (IOException ioe) { throw new StripesJspException("IOException while writing output in UrlTag.", ioe); } // Restore state and go on with the page setUrl(originalURL); this.parameters.clear(); return EVAL_PAGE; } /** Sets the (optional) event name that the link will trigger. */ public void setEvent(String event) { this.event = event; } /** Gets the (optional) event name that the link will trigger. */ public String getEvent() { return event; } /** * Sets the bean class (String FQN or Class) to generate a link for. Provides an * alternative to using href for targetting ActionBeans. * * @param beanclass the name of an ActionBean class, or Class object */ public void setBeanclass(Object beanclass) { this.beanclass = beanclass; } /** * Gets the bean class (String FQN or Class) to generate a link for. Provides an * alternative to using href for targetting ActionBeans. * * @return the name of an ActionBean class, or Class object */ public Object getBeanclass() { return beanclass; } /////////////////////////////////////////////////////////////////////////// // Additional HTML Attributes supported by the tag /////////////////////////////////////////////////////////////////////////// public void setUrl(String url) { set("url", url); } public String getUrl() { return get("url"); } } UrlParamTag.java ------------------------------------------------------------------------------ package net.sourceforge.stripes.tag; import javax.servlet.jsp.tagext.BodyTag; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.JspException; /** * Used to supply parameters when nested inside a URL tag. The value is either obtained from * the value attribute, or if that is not present, then the body of the tag. Once the value has * been established the parent link tag is looked for, and the parameter is handed over to it * for inclusion in the link url. * * @author Tim Fennell */ public class UrlParamTag implements BodyTag { private String name; private Object value; private BodyContent bodyContent; private Tag parentTag; private PageContext pageContext; /** Sets the value of the parameter(s) to be added to the URL. */ public void setValue(Object value) { this.value = value; } /** Gets the value attribute, as set with setValue(). */ public Object getValue() { return value; } /** Sets the name of the parameter(s) that will be added to the URL. */ public void setName(String name) { this.name = name; } /** Gets the name of the parameter(s) that will be added to the URL. */ public String getName() { return name; } /** Used by the container to set the contents of the body of the tag. */ public void setBodyContent(BodyContent bodyContent) { this.bodyContent = bodyContent; } /** Used by the container to set the page context for the tag. */ public void setPageContext(PageContext pageContext) { this.pageContext = pageContext; } /** Used by the container to provide the tag with access to it's parent tag on the page. */ public void setParent(Tag tag) { this.parentTag = tag; } /** Required spec method to allow others to access the parent of the tag. */ public Tag getParent() { return this.parentTag; } /** Does nothing. */ public void doInitBody() throws JspException { /* Do Nothing */ } /** * Does nothing. * @return SKIP_BODY in all cases. */ public int doAfterBody() throws JspException { return SKIP_BODY; } /** * Does nothing. * @return EVAL_BODY_BUFFERED in all cases. */ public int doStartTag() throws JspException { return EVAL_BODY_BUFFERED; } /** * Figures out what to use as the value, and then finds the parent link and adds * the parameter. * @return EVAL_PAGE in all cases. */ public int doEndTag() throws JspException { Object valueToSet = value; // First figure out what value to send to the parent link tag if (value == null) { if (this.bodyContent == null) { valueToSet = ""; } else { valueToSet = this.bodyContent.getString(); } } // Find the parent link tag Tag urlTag = this.parentTag; while (urlTag != null && !(urlTag instanceof UrlTag)) { urlTag = urlTag.getParent(); } ((UrlTag) urlTag).addParameter(name, valueToSet); return EVAL_PAGE; } /** Does nothing. */ public void release() { /* Do nothing. */ } } stripes.tld additions ------------------------------------------------------------------------------------------------------------ <?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <description> Provides extended tags for use with the Stripes presentation framework. </description> <display-name>Stripes Extended Tag Library</display-name> <tlib-version>1.0</tlib-version> <short-name>stripes-ext</short-name> <uri>META-INF/stripes-ext.tld</uri> <tag> <description><![CDATA[ <p>Tag that generates URL links for pages and ActionBean events within a Stripes application. Works in concert with zero or more nested url-param tags in order to allow addition of arbitrary parameters to any URL. The body of the tag, minus any url-param tags, is trimmed for whitespace at either end, and is then used as the contents of the link body.</p> <p>There are two attributes which are not a mirrors of attributes on the HTML anchor tag. The first is the 'event' attribute. This allows specification of a specific event to trigger when linking to an ActionBean URL. The second is 'beanclass' which allows the specification of the class name or Class instance for an ActionBean as an alternative to specifying the 'href' attribute.</p> ]]></description> <display-name>url</display-name> <name>url</name> <tag-class>net.sourceforge.stripes.tag.UrlTag</tag-class> <body-content>JSP</body-content> <attribute> <description> The (optional) event that should be fired if the link is to an ActionBean. If not supplied then the tag will not render an explicit event (but one may by built in to the URL/href supplied). </description> <name>event</name><required>false</required><rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description> The fully qualified name of an ActionBean class, or alternatively a Class instance for an ActionBean class. An alternative to the 'href' attribute, the 'beanclass' attribute will generate an href appropriate for the ActionBean identified. Note that if an ActionBean that does not yet exist is identified an exception will be thrown! </description> <name>beanclass</name><required>true</required><rtexprvalue>true</rtexprvalue> <type>java.lang.Object</type> </attribute> <attribute> <description>The character set used to encode the referenced page. (HTML Pass-through)</description> <name>charset</name><required>false</required><rtexprvalue>true</rtexprvalue> </attribute> <dynamic-attributes>false</dynamic-attributes> </tag> <tag> <description><![CDATA[ Used to add parameters to a URL that has been created with a stripes:url tag. If the value attribute is present it will be used. If the value attribute is not present, then the body of the tag will be used as the parameter value. The value attribute may identify either a scalar value, an Array or a Collection. In the latter two cases a URL parameter will be added per value in the Array or Collection. ]]></description> <display-name>url-param</display-name> <name>url-param</name> <tag-class>net.sourceforge.stripes.tag.UrlParamTag</tag-class> <body-content>JSP</body-content> <attribute> <description>The name of the URL parameter.</description> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description>The value (or values) of the URL parameter.</description> <name>value</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>java.lang.Object</type> </attribute> </tag> </taglib> -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://mc4j.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira ------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Stripes-development mailing list Stripes-development@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-development