Index: src/main/java/org/displaytag/model/Column.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/model/Column.java,v retrieving revision 1.33 diff -u -r1.33 Column.java --- src/main/java/org/displaytag/model/Column.java 20 Dec 2005 21:16:10 -0000 1.33 +++ src/main/java/org/displaytag/model/Column.java 23 Dec 2005 02:08:00 -0000 @@ -248,7 +248,7 @@ private Href getColumnHref(String columnContent) throws ObjectLookupException { // copy href - Href colHref = new Href(this.header.getHref()); + Href colHref = (Href)this.header.getHref().clone(); // do we need to add a param? if (this.header.getParamName() != null) Index: src/main/java/org/displaytag/pagination/Pagination.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/pagination/Pagination.java,v retrieving revision 1.17 diff -u -r1.17 Pagination.java --- src/main/java/org/displaytag/pagination/Pagination.java 29 Oct 2005 15:07:14 -0000 1.17 +++ src/main/java/org/displaytag/pagination/Pagination.java 23 Dec 2005 02:08:00 -0000 @@ -16,6 +16,7 @@ import java.util.Iterator; import java.util.List; +import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.logging.Log; @@ -234,7 +235,7 @@ Integer pageNumber = new Integer(page.getNumber()); - String urlString = ((Href) this.href.clone()).addParameter(this.pageParam, pageNumber).toString(); + String urlString = ((Href) this.href.clone()).addParameter(this.pageParam, pageNumber.toString()).toString(); // needed for MessageFormat : page number/url Object[] pageObjects = {pageNumber, urlString}; @@ -268,10 +269,10 @@ // {6} total pages Object[] pageObjects = { numberedPageString, - ((Href) this.href.clone()).addParameter(this.pageParam, getFirst()), - ((Href) this.href.clone()).addParameter(this.pageParam, getPrevious()), - ((Href) this.href.clone()).addParameter(this.pageParam, getNext()), - ((Href) this.href.clone()).addParameter(this.pageParam, getLast()), + ((Href) this.href.clone()).addParameter(this.pageParam, ObjectUtils.toString(getFirst(), null)), + ((Href) this.href.clone()).addParameter(this.pageParam, ObjectUtils.toString(getPrevious(), null)), + ((Href) this.href.clone()).addParameter(this.pageParam, ObjectUtils.toString(getNext(), null)), + ((Href) this.href.clone()).addParameter(this.pageParam, ObjectUtils.toString(getLast(), null)), this.currentPage, this.isLast() ? this.currentPage : this.lastPage}; // this.lastPage is null if the last page is displayed Index: src/main/java/org/displaytag/render/HtmlTableWriter.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/render/HtmlTableWriter.java,v retrieving revision 1.3 diff -u -r1.3 HtmlTableWriter.java --- src/main/java/org/displaytag/render/HtmlTableWriter.java 19 Dec 2005 21:20:45 -0000 1.3 +++ src/main/java/org/displaytag/render/HtmlTableWriter.java 23 Dec 2005 02:08:01 -0000 @@ -416,7 +416,7 @@ private Href getSortingHref(HeaderCell headerCell) { // costruct Href from base href, preserving parameters - Href href = new Href(this.baseHref); + Href href = (Href)this.baseHref.clone(); if (this.paginatedList == null) { @@ -539,7 +539,7 @@ || (this.paginatedList != null)) { // create a new href - Href navigationHref = new Href(this.baseHref); + Href navigationHref = (Href)this.baseHref.clone(); write(this.listHelper.getSearchResultsSummary()); @@ -567,7 +567,7 @@ private void writeExportLinks() { // Figure out what formats they want to export, make up a little string - Href exportHref = new Href(this.baseHref); + Href exportHref = (Href)this.baseHref.clone(); StringBuffer buffer = new StringBuffer(200); Iterator iterator = MediaTypeEnum.iterator(); Index: src/main/java/org/displaytag/tags/ColumnTag.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/tags/ColumnTag.java,v retrieving revision 1.65 diff -u -r1.65 ColumnTag.java --- src/main/java/org/displaytag/tags/ColumnTag.java 21 Dec 2005 10:19:00 -0000 1.65 +++ src/main/java/org/displaytag/tags/ColumnTag.java 23 Dec 2005 02:08:02 -0000 @@ -40,6 +40,7 @@ import org.displaytag.model.HeaderCell; import org.displaytag.properties.MediaTypeEnum; import org.displaytag.properties.SortOrderEnum; +import org.displaytag.util.DefaultHref; import org.displaytag.util.Href; import org.displaytag.util.HtmlAttributeMap; import org.displaytag.util.MediaUtil; @@ -58,7 +59,7 @@ *

* @author mraible * @author Fabrizio Giustina - * @version $Revision: 1.65 $ ($Author: fgiust $) + * @version $Revision: 1.64 $ ($Author: fgiust $) */ public class ColumnTag extends BodyTagSupport implements MediaUtil.SupportsMedia { @@ -380,7 +381,7 @@ // call encodeURL to preserve session id when cookies are disabled String encodedHref = ((HttpServletResponse) this.pageContext.getResponse()).encodeURL(StringUtils .defaultString(value)); - this.href = new Href(encodedHref); + this.href = new DefaultHref(encodedHref); } /** @@ -394,7 +395,7 @@ // call encodeURL to preserve session id when cookies are disabled String encodedHref = ((HttpServletResponse) this.pageContext.getResponse()).encodeURL(StringUtils .defaultString(req.getContextPath() + value)); - this.href = new Href(encodedHref); + this.href = new DefaultHref(encodedHref); } /** @@ -731,11 +732,11 @@ // empty base url, use href with parameters from parent table if (StringUtils.isEmpty(this.href.getBaseUrl())) { - colHref = new Href(tableTag.getBaseHref()); + colHref = (Href)tableTag.getBaseHref().clone(); } else { - colHref = new Href(this.href); + colHref = (Href)this.href.clone(); } if (this.paramId != null) @@ -775,7 +776,7 @@ Object paramValue = tableTag.evaluateExpression(expression.toString()); // add parameter - colHref.addParameter(this.paramId, paramValue); + colHref.addParameter(this.paramId, paramValue.toString()); } else { Index: src/main/java/org/displaytag/tags/TableTag.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/tags/TableTag.java,v retrieving revision 1.111 diff -u -r1.111 TableTag.java --- src/main/java/org/displaytag/tags/TableTag.java 19 Dec 2005 21:20:44 -0000 1.111 +++ src/main/java/org/displaytag/tags/TableTag.java 23 Dec 2005 02:08:03 -0000 @@ -59,6 +59,7 @@ import org.displaytag.properties.TableProperties; import org.displaytag.render.HtmlTableWriter; import org.displaytag.util.CollectionUtil; +import org.displaytag.util.DefaultHref; import org.displaytag.util.DependencyChecker; import org.displaytag.util.Href; import org.displaytag.util.ParamEncoder; @@ -1120,7 +1121,7 @@ // call encodeURL to preserve session id when cookies are disabled fullURI = ((HttpServletResponse) this.pageContext.getResponse()).encodeURL(fullURI); - this.baseHref = new Href(fullURI); + this.baseHref = new DefaultHref(fullURI); // ... and copy parameters from the current request Map parameterMap = normalHref.getParameterMap(); Index: src/main/java/org/displaytag/util/DefaultRequestHelper.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/util/DefaultRequestHelper.java,v retrieving revision 1.12 diff -u -r1.12 DefaultRequestHelper.java --- src/main/java/org/displaytag/util/DefaultRequestHelper.java 11 Sep 2005 17:37:38 -0000 1.12 +++ src/main/java/org/displaytag/util/DefaultRequestHelper.java 23 Dec 2005 02:08:03 -0000 @@ -71,7 +71,7 @@ { String requestURI = this.request.getRequestURI(); // call encodeURL to preserve session id when cookies are disabled - Href href = new Href(this.response.encodeURL(requestURI)); + Href href = new DefaultHref(this.response.encodeURL(requestURI)); href.setParameterMap(getParameterMap()); return href; } Index: src/main/java/org/displaytag/util/Href.java =================================================================== RCS file: /cvsroot/displaytag/displaytag/src/main/java/org/displaytag/util/Href.java,v retrieving revision 1.26 diff -u -r1.26 Href.java --- src/main/java/org/displaytag/util/Href.java 19 Nov 2004 20:16:11 -0000 1.26 +++ src/main/java/org/displaytag/util/Href.java 23 Dec 2005 02:08:03 -0000 @@ -12,175 +12,30 @@ package org.displaytag.util; import java.io.Serializable; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; /** - * Object representing an URI (the href parameter of an <a> tag). Provides methods to insert new parameters. It + * Interface representing an URI (the href parameter of an <a> tag). Provides methods to insert new parameters. It * doesn't support multiple parameter values * @author Fabrizio Giustina * @version $Revision: 1.26 $ ($Author: fgiust $) */ -public class Href implements Cloneable, Serializable +public interface Href extends Cloneable, Serializable { - - /** - * D1597A17A6. - */ - private static final long serialVersionUID = 899149338534L; - - /** - * Base url for the href. - */ - private String url; - - /** - * Url parameters. - */ - private Map parameters; - - /** - * Anchor (to be added at the end of URL). - */ - private String anchor; - - /** - * Construct a new Href parsing a URL. Parameters are stripped from the base url and saved in the parameters map. - * @param baseUrl String - */ - public Href(String baseUrl) - { - this.parameters = new HashMap(); - - String noAnchorUrl; - int anchorposition = baseUrl.indexOf('#'); - - // extract anchor from url - if (anchorposition != -1) - { - noAnchorUrl = baseUrl.substring(0, anchorposition); - this.anchor = baseUrl.substring(anchorposition + 1); - } - else - { - noAnchorUrl = baseUrl; - } - - if (noAnchorUrl.indexOf('?') == -1) - { - // simple url, no parameters - this.url = noAnchorUrl; - return; - } - - // the Url already has parameters, put them in the parameter Map - StringTokenizer tokenizer = new StringTokenizer(noAnchorUrl, "?"); //$NON-NLS-1$ - - if (baseUrl.startsWith("?")) //$NON-NLS-1$ - { - // support fake URI's which are just parameters to use with the current uri - url = TagConstants.EMPTY_STRING; - } - else - { - // base url (before "?") - url = tokenizer.nextToken(); - } - - if (!tokenizer.hasMoreTokens()) - { - return; - } - - // process parameters - StringTokenizer paramTokenizer = new StringTokenizer(tokenizer.nextToken(), "&"); //$NON-NLS-1$ - - // split parameters (key=value) - while (paramTokenizer.hasMoreTokens()) - { - // split key and value ... - String[] keyValue = StringUtils.split(paramTokenizer.nextToken(), '='); - - // encode name/value to prevent css - String escapedKey = StringEscapeUtils.escapeHtml(keyValue[0]); - String escapedValue = keyValue.length > 1 - ? StringEscapeUtils.escapeHtml(keyValue[1]) - : TagConstants.EMPTY_STRING; - - if (!this.parameters.containsKey(escapedKey)) - { - // ... and add it to the map - this.parameters.put(escapedKey, escapedValue); - } - else - { - // additional value for an existing parameter - Object previousValue = this.parameters.get(escapedKey); - if (previousValue != null && previousValue.getClass().isArray()) - { - Object[] previousArray = (Object[]) previousValue; - Object[] newArray = new Object[previousArray.length + 1]; - - int j; - - for (j = 0; j < previousArray.length; j++) - { - newArray[j] = previousArray[j]; - } - - newArray[j] = escapedValue; - this.parameters.put(escapedKey, newArray); - } - else - { - this.parameters.put(escapedKey, new Object[]{previousValue, escapedValue}); - } - } - } - } - - /** - * Constructor for Href. - * @param href Href - */ - public Href(Href href) - { - this.url = href.url; - this.anchor = href.anchor; - // getParameterMap() returns a copy - this.parameters = href.getParameterMap(); - } - /** * Adds a parameter to the href. * @param name String * @param value Object * @return this Href instance, useful for concatenation. */ - public Href addParameter(String name, Object value) - { - this.parameters.put(name, value); - return this; - } + public Href addParameter(String name, String value); /** * Removes a parameter from the href. * @param name String */ - public void removeParameter(String name) - { - // warning, param names are escaped - this.parameters.remove(StringEscapeUtils.escapeHtml(name)); - } + public void removeParameter(String name); /** * Adds an int parameter to the href. @@ -188,216 +43,64 @@ * @param value int * @return this Href instance, useful for concatenation. */ - public Href addParameter(String name, int value) - { - this.parameters.put(name, new Integer(value)); - return this; - } + public Href addParameter(String name, int value); /** * Getter for the map containing link parameters. The returned map is always a copy and not the original instance. * @return parameter Map (copy) */ - public Map getParameterMap() - { - Map copyMap = new HashMap(this.parameters.size()); - copyMap.putAll(this.parameters); - return copyMap; - } + public Map getParameterMap(); /** * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before * added. Any parameter already present in the href object is removed. * @param parametersMap Map containing parameters */ - public void setParameterMap(Map parametersMap) - { - // create a new HashMap - this.parameters = new HashMap(parametersMap.size()); - - // copy the parameters - addParameterMap(parametersMap); - } - + public void setParameterMap(Map parametersMap); + /** * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before * added. Parameters in the original href are kept and not overridden. * @param parametersMap Map containing parameters */ - public void addParameterMap(Map parametersMap) - { - // handle nulls - if (parametersMap == null) - { - return; - } - - // copy value, escaping html - Iterator mapIterator = parametersMap.entrySet().iterator(); - while (mapIterator.hasNext()) - { - Map.Entry entry = (Map.Entry) mapIterator.next(); - String key = StringEscapeUtils.escapeHtml((String) entry.getKey()); - - // don't overwrite parameters - if (!this.parameters.containsKey(key)) - { - Object value = entry.getValue(); - - if (value != null) - { - if (value.getClass().isArray()) - { - String[] values = (String[]) value; - for (int i = 0; i < values.length; i++) - { - values[i] = StringEscapeUtils.escapeHtml(values[i]); - } - } - else - { - value = StringEscapeUtils.escapeHtml(value.toString()); - } - } - - this.parameters.put(key, value); - } - } - } + public void addParameterMap(Map parametersMap); /** * Getter for the base url (without parameters). * @return String */ - public String getBaseUrl() - { - return this.url; - } + public String getBaseUrl(); /** * Returns the URI anchor. * @return anchor or null if no anchor has been set. */ - public String getAnchor() - { - return this.anchor; - } + public String getAnchor(); /** * Setter for the URI anchor. * @param name string to be used as anchor name (without #). */ - public void setAnchor(String name) - { - this.anchor = name; - } + public void setAnchor(String name); /** - * toString: output the full url with parameters. - * @return String + * @return The full url with parameters. + * @see java.lang.Object#toString() */ - public String toString() - { - StringBuffer buffer = new StringBuffer(30); - - buffer.append(this.url); - - if (this.parameters.size() > 0) - { - buffer.append('?'); - Set parameterSet = this.parameters.entrySet(); - - Iterator iterator = parameterSet.iterator(); - - while (iterator.hasNext()) - { - Map.Entry entry = (Map.Entry) iterator.next(); - - Object key = entry.getKey(); - Object value = entry.getValue(); - - if (value == null) - { - buffer.append(key).append('='); // no value - } - else if (value.getClass().isArray()) - { - Object[] values = (Object[]) value; - for (int i = 0; i < values.length; i++) - { - if (i > 0) - { - buffer.append(TagConstants.AMPERSAND); - } - - buffer.append(key).append('=').append(values[i]); - } - } - else - { - buffer.append(key).append('=').append(value); - } - - if (iterator.hasNext()) - { - buffer.append(TagConstants.AMPERSAND); - } - } - } - - if (this.anchor != null) - { - buffer.append('#'); - buffer.append(this.anchor); - } - - return buffer.toString(); - } + public String toString(); /** * @see java.lang.Object#clone() */ - public Object clone() - { - Href href = null; - - try - { - href = (Href) super.clone(); - } - catch (CloneNotSupportedException e) - { - // should never happen - } - - href.parameters = new HashMap(this.parameters); - return href; - } + public Object clone(); /** * @see java.lang.Object#equals(Object) */ - public boolean equals(Object object) - { - if (!(object instanceof Href)) - { - return false; - } - Href rhs = (Href) object; - return new EqualsBuilder().append(this.parameters, rhs.parameters).append(this.url, rhs.url).append( - this.anchor, - rhs.anchor).isEquals(); - } + public boolean equals(Object object); /** * @see java.lang.Object#hashCode() */ - public int hashCode() - { - return new HashCodeBuilder(1313733113, -431360889) - .append(this.parameters) - .append(this.url) - .append(this.anchor) - .toHashCode(); - } + public int hashCode(); } \ No newline at end of file Index: src/test/java/org/displaytag/util/HrefTest.java =================================================================== RCS file: src/test/java/org/displaytag/util/HrefTest.java diff -N src/test/java/org/displaytag/util/HrefTest.java --- src/test/java/org/displaytag/util/HrefTest.java 30 Dec 2004 20:05:41 -0000 1.13 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,289 +0,0 @@ -package org.displaytag.util; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestCase; - -import org.displaytag.test.URLAssert; - - -/** - * Test case for org.displaytag.util.Href. - * @author Fabrizio Giustina - * @version $Revision: 1.13 $ ($Author: fgiust $) - */ -public class HrefTest extends TestCase -{ - - /** - * @see junit.framework.TestCase#getName() - */ - public String getName() - { - return getClass().getName() + "." + super.getName(); - } - - /** - * Test a simple URL without parameters. - */ - public final void testSimpleHref() - { - String url = "http://www.displaytag.org/displaytag"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for URLs containing parameters. - */ - public final void testHrefWithParameters() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for URLs containing parameters without values. - */ - public final void testHrefParamWithoutValue() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for URLs containing multiple parameters (some of them without values). - */ - public final void testHrefMultipleParamWithoutValue() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1¶m2=2"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for URLs containing parameters with multiple values. - */ - public final void testHrefWithMultipleParameters() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2¶m2=3¶m2=4¶m2="; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for urls containing anchors. - */ - public final void testHrefWithAnchor() - { - String url = "http://www.displaytag.org/displaytag/index.jsp#thisanchor"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test href with empty anchor. - */ - public final void testHrefWithEmptyAnchor() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for urls containin anchors and parameters. - */ - public final void testHrefWithAnchorAndParameters() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test for urls containing quotes. - */ - public final void testHrefWithQuotes() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=aquote'test"; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * Test the generation of an Href object from another Href. - */ - public final void testHrefCopy() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - Href copy = new Href(href); - URLAssert.assertEquals(copy.toString(), href.toString()); - } - - /** - * Test the clone() implementation. - */ - public final void testClone() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - Href clone = (Href) href.clone(); - assertEquals(href, clone); - - clone.addParameter("onlyinclone", "1"); - assertFalse(href.equals(clone)); - } - - /** - * Tests the equals() implementation. - */ - public final void testEquals() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - Href href2 = new Href(url); - assertEquals(href, href2); - } - - /** - * Test for added parameters. - */ - public final void testAddParameter() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - href.addParameter("param3", "value3"); - href.addParameter("param4", 4); - String newUrl = href.toString(); - URLAssert.assertEquals( - "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2¶m3=value3¶m4=4#thisanchor", - newUrl); - } - - /** - * test for setParameterMap(). - */ - public final void testSetParameterMap() - { - String url = "http://www.displaytag.org/displaytag/index.jsp#thisanchor"; - Href href = new Href(url); - - Map parameterMap = new HashMap(); - parameterMap.put("new1", "new1value"); - parameterMap.put("new2", "new2value"); - parameterMap.put("new3", null); - href.setParameterMap(parameterMap); - - String newUrl = href.toString(); - URLAssert.assertEquals( - "http://www.displaytag.org/displaytag/index.jsp?new1=new1value&new2=new2value&new3=#thisanchor", - newUrl); - } - - /** - * test for addParameterMap(). - */ - public final void testAddParameterMap() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1#thisanchor"; - Href href = new Href(url); - - Map parameterMap = new HashMap(); - parameterMap.put("new1", "new1value"); - parameterMap.put("new2", "new2value"); - parameterMap.put("new3", null); - href.addParameterMap(parameterMap); - - String newUrl = href.toString(); - URLAssert.assertEquals( - "http://www.displaytag.org/displaytag/index.jsp?param1=1&new1=new1value&new2=new2value&new3=#thisanchor", - newUrl); - - } - - /** - * test for addParameterMap(). - */ - public final void testAddParameterMapMultiValue() - { - String url = "http://www.displaytag.org/displaytag/index.jsp"; - Href href = new Href(url); - - Map parameterMap = new HashMap(); - parameterMap.put("param1", new String[]{"à", "<"}); - href.addParameterMap(parameterMap); - - String newUrl = href.toString(); - assertEquals("http://www.displaytag.org/displaytag/index.jsp?param1=à&param1=<", newUrl); - - } - - /** - * test for addParameterMap() with overriding parameters. - */ - public final void testAddParameterMapOverridingParameters() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=original#thisanchor"; - Href href = new Href(url); - - Map parameterMap = new HashMap(); - parameterMap.put("param1", "original"); - parameterMap.put("new1", "new1value"); - href.addParameterMap(parameterMap); - - String newUrl = href.toString(); - URLAssert.assertEquals( - "http://www.displaytag.org/displaytag/index.jsp?param1=original&new1=new1value#thisanchor", - newUrl); - - } - - /** - * test for base url extraction. - */ - public final void testGetBaseUrl() - { - String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - assertEquals(href.getBaseUrl(), "http://www.displaytag.org/displaytag/index.jsp"); - } - - /** - * Complex test. - */ - public final void testComplex() - { - String url = "http://www.displaytag.org/EProcurement/do/searchWorkflowAction?initiator=AVINASH&wfid=" - + "&approvedTDate=&initiatedFDate=&status=default&d-3824-p=2&initiatedTDate=04/28/2004" - + "&approvedFDate=&method=search&approver="; - Href href = new Href(url); - String newUrl = href.toString(); - URLAssert.assertEquals(url, newUrl); - } - - /** - * test for url without base. - */ - public final void testNoBaseUrl() - { - String url = "?param1=1¶m2=2#thisanchor"; - Href href = new Href(url); - assertEquals(href.getBaseUrl(), ""); - URLAssert.assertEquals(url, href.toString()); - } - -} \ No newline at end of file Index: src/main/java/org/displaytag/util/DefaultHref.java =================================================================== RCS file: src/main/java/org/displaytag/util/DefaultHref.java diff -N src/main/java/org/displaytag/util/DefaultHref.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/java/org/displaytag/util/DefaultHref.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,385 @@ +/** + * Licensed under the Artistic License; you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://displaytag.sourceforge.net/license.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +package org.displaytag.util; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + + +/** + * @author Fabrizio Giustina + * @version $Revision: 1.26 $ ($Author: fgiust $) + */ +public class DefaultHref implements Href +{ + + /** + * D1597A17A6. + */ + private static final long serialVersionUID = 899149338534L; + + /** + * Base url for the href. + */ + private String url; + + /** + * Url parameters. + */ + private Map parameters; + + /** + * Anchor (to be added at the end of URL). + */ + private String anchor; + + /** + * Construct a new Href parsing a URL. Parameters are stripped from the base url and saved in the parameters map. + * @param baseUrl String + */ + public DefaultHref(String baseUrl) + { + this.parameters = new HashMap(); + + String noAnchorUrl; + int anchorposition = baseUrl.indexOf('#'); + + // extract anchor from url + if (anchorposition != -1) + { + noAnchorUrl = baseUrl.substring(0, anchorposition); + this.anchor = baseUrl.substring(anchorposition + 1); + } + else + { + noAnchorUrl = baseUrl; + } + + if (noAnchorUrl.indexOf('?') == -1) + { + // simple url, no parameters + this.url = noAnchorUrl; + return; + } + + // the Url already has parameters, put them in the parameter Map + StringTokenizer tokenizer = new StringTokenizer(noAnchorUrl, "?"); //$NON-NLS-1$ + + if (baseUrl.startsWith("?")) //$NON-NLS-1$ + { + // support fake URI's which are just parameters to use with the current uri + url = TagConstants.EMPTY_STRING; + } + else + { + // base url (before "?") + url = tokenizer.nextToken(); + } + + if (!tokenizer.hasMoreTokens()) + { + return; + } + + // process parameters + StringTokenizer paramTokenizer = new StringTokenizer(tokenizer.nextToken(), "&"); //$NON-NLS-1$ + + // split parameters (key=value) + while (paramTokenizer.hasMoreTokens()) + { + // split key and value ... + String[] keyValue = StringUtils.split(paramTokenizer.nextToken(), '='); + + // encode name/value to prevent css + String escapedKey = StringEscapeUtils.escapeHtml(keyValue[0]); + String escapedValue = keyValue.length > 1 + ? StringEscapeUtils.escapeHtml(keyValue[1]) + : TagConstants.EMPTY_STRING; + + if (!this.parameters.containsKey(escapedKey)) + { + // ... and add it to the map + this.parameters.put(escapedKey, escapedValue); + } + else + { + // additional value for an existing parameter + Object previousValue = this.parameters.get(escapedKey); + if (previousValue != null && previousValue.getClass().isArray()) + { + Object[] previousArray = (Object[]) previousValue; + Object[] newArray = new Object[previousArray.length + 1]; + + int j; + + for (j = 0; j < previousArray.length; j++) + { + newArray[j] = previousArray[j]; + } + + newArray[j] = escapedValue; + this.parameters.put(escapedKey, newArray); + } + else + { + this.parameters.put(escapedKey, new Object[]{previousValue, escapedValue}); + } + } + } + } + + /** + * Adds a parameter to the href. + * @param name String + * @param value Object + * @return this Href instance, useful for concatenation. + */ + public Href addParameter(String name, String value) + { + this.parameters.put(name, value); + return this; + } + + /** + * Removes a parameter from the href. + * @param name String + */ + public void removeParameter(String name) + { + // warning, param names are escaped + this.parameters.remove(StringEscapeUtils.escapeHtml(name)); + } + + /** + * Adds an int parameter to the href. + * @param name String + * @param value int + * @return this Href instance, useful for concatenation. + */ + public Href addParameter(String name, int value) + { + this.parameters.put(name, new Integer(value)); + return this; + } + + /** + * Getter for the map containing link parameters. The returned map is always a copy and not the original instance. + * @return parameter Map (copy) + */ + public Map getParameterMap() + { + Map copyMap = new HashMap(this.parameters.size()); + copyMap.putAll(this.parameters); + return copyMap; + } + + /** + * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before + * added. Any parameter already present in the href object is removed. + * @param parametersMap Map containing parameters + */ + public void setParameterMap(Map parametersMap) + { + // create a new HashMap + this.parameters = new HashMap(parametersMap.size()); + + // copy the parameters + addParameterMap(parametersMap); + } + + /** + * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before + * added. Parameters in the original href are kept and not overridden. + * @param parametersMap Map containing parameters + */ + public void addParameterMap(Map parametersMap) + { + // handle nulls + if (parametersMap == null) + { + return; + } + + // copy value, escaping html + Iterator mapIterator = parametersMap.entrySet().iterator(); + while (mapIterator.hasNext()) + { + Map.Entry entry = (Map.Entry) mapIterator.next(); + String key = StringEscapeUtils.escapeHtml((String) entry.getKey()); + + // don't overwrite parameters + if (!this.parameters.containsKey(key)) + { + Object value = entry.getValue(); + + if (value != null) + { + if (value.getClass().isArray()) + { + String[] values = (String[]) value; + for (int i = 0; i < values.length; i++) + { + values[i] = StringEscapeUtils.escapeHtml(values[i]); + } + } + else + { + value = StringEscapeUtils.escapeHtml(value.toString()); + } + } + + this.parameters.put(key, value); + } + } + } + + /** + * Getter for the base url (without parameters). + * @return String + */ + public String getBaseUrl() + { + return this.url; + } + + /** + * Returns the URI anchor. + * @return anchor or null if no anchor has been set. + */ + public String getAnchor() + { + return this.anchor; + } + + /** + * Setter for the URI anchor. + * @param name string to be used as anchor name (without #). + */ + public void setAnchor(String name) + { + this.anchor = name; + } + + /** + * toString: output the full url with parameters. + * @return String + */ + public String toString() + { + StringBuffer buffer = new StringBuffer(30); + + buffer.append(this.url); + + if (this.parameters.size() > 0) + { + buffer.append('?'); + Set parameterSet = this.parameters.entrySet(); + + Iterator iterator = parameterSet.iterator(); + + while (iterator.hasNext()) + { + Map.Entry entry = (Map.Entry) iterator.next(); + + Object key = entry.getKey(); + Object value = entry.getValue(); + + if (value == null) + { + buffer.append(key).append('='); // no value + } + else if (value.getClass().isArray()) + { + Object[] values = (Object[]) value; + for (int i = 0; i < values.length; i++) + { + if (i > 0) + { + buffer.append(TagConstants.AMPERSAND); + } + + buffer.append(key).append('=').append(values[i]); + } + } + else + { + buffer.append(key).append('=').append(value); + } + + if (iterator.hasNext()) + { + buffer.append(TagConstants.AMPERSAND); + } + } + } + + if (this.anchor != null) + { + buffer.append('#'); + buffer.append(this.anchor); + } + + return buffer.toString(); + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() + { + final DefaultHref href; + try { + href = (DefaultHref)super.clone(); + } + catch (CloneNotSupportedException cnse) { + throw new RuntimeException("Caught CloneNotSupportedException in Clonable class.", cnse); + } + + href.parameters = new HashMap(this.parameters); + return href; + } + + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object object) + { + if (!(object instanceof DefaultHref)) + { + return false; + } + DefaultHref rhs = (DefaultHref) object; + return new EqualsBuilder().append(this.parameters, rhs.parameters).append(this.url, rhs.url).append( + this.anchor, + rhs.anchor).isEquals(); + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() + { + return new HashCodeBuilder(1313733113, -431360889) + .append(this.parameters) + .append(this.url) + .append(this.anchor) + .toHashCode(); + } +} Index: src/test/java/org/displaytag/util/DefaultHrefTest.java =================================================================== RCS file: src/test/java/org/displaytag/util/DefaultHrefTest.java diff -N src/test/java/org/displaytag/util/DefaultHrefTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/test/java/org/displaytag/util/DefaultHrefTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,289 @@ +package org.displaytag.util; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.displaytag.test.URLAssert; + + +/** + * Test case for org.displaytag.util.Href. + * @author Fabrizio Giustina + * @version $Revision: 1.13 $ ($Author: fgiust $) + */ +public class DefaultHrefTest extends TestCase +{ + + /** + * @see junit.framework.TestCase#getName() + */ + public String getName() + { + return getClass().getName() + "." + super.getName(); + } + + /** + * Test a simple URL without parameters. + */ + public final void testSimpleHref() + { + String url = "http://www.displaytag.org/displaytag"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for URLs containing parameters. + */ + public final void testHrefWithParameters() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for URLs containing parameters without values. + */ + public final void testHrefParamWithoutValue() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for URLs containing multiple parameters (some of them without values). + */ + public final void testHrefMultipleParamWithoutValue() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1¶m2=2"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for URLs containing parameters with multiple values. + */ + public final void testHrefWithMultipleParameters() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2¶m2=3¶m2=4¶m2="; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for urls containing anchors. + */ + public final void testHrefWithAnchor() + { + String url = "http://www.displaytag.org/displaytag/index.jsp#thisanchor"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test href with empty anchor. + */ + public final void testHrefWithEmptyAnchor() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for urls containin anchors and parameters. + */ + public final void testHrefWithAnchorAndParameters() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test for urls containing quotes. + */ + public final void testHrefWithQuotes() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=aquote'test"; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * Test the generation of an Href object from another Href. + */ + public final void testHrefCopy() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + Href copy = (Href)href.clone(); + URLAssert.assertEquals(copy.toString(), href.toString()); + } + + /** + * Test the clone() implementation. + */ + public final void testClone() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + Href clone = (Href) href.clone(); + assertEquals(href, clone); + + clone.addParameter("onlyinclone", "1"); + assertFalse(href.equals(clone)); + } + + /** + * Tests the equals() implementation. + */ + public final void testEquals() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + Href href2 = new DefaultHref(url); + assertEquals(href, href2); + } + + /** + * Test for added parameters. + */ + public final void testAddParameter() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + href.addParameter("param3", "value3"); + href.addParameter("param4", 4); + String newUrl = href.toString(); + URLAssert.assertEquals( + "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2¶m3=value3¶m4=4#thisanchor", + newUrl); + } + + /** + * test for setParameterMap(). + */ + public final void testSetParameterMap() + { + String url = "http://www.displaytag.org/displaytag/index.jsp#thisanchor"; + Href href = new DefaultHref(url); + + Map parameterMap = new HashMap(); + parameterMap.put("new1", "new1value"); + parameterMap.put("new2", "new2value"); + parameterMap.put("new3", null); + href.setParameterMap(parameterMap); + + String newUrl = href.toString(); + URLAssert.assertEquals( + "http://www.displaytag.org/displaytag/index.jsp?new1=new1value&new2=new2value&new3=#thisanchor", + newUrl); + } + + /** + * test for addParameterMap(). + */ + public final void testAddParameterMap() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1#thisanchor"; + Href href = new DefaultHref(url); + + Map parameterMap = new HashMap(); + parameterMap.put("new1", "new1value"); + parameterMap.put("new2", "new2value"); + parameterMap.put("new3", null); + href.addParameterMap(parameterMap); + + String newUrl = href.toString(); + URLAssert.assertEquals( + "http://www.displaytag.org/displaytag/index.jsp?param1=1&new1=new1value&new2=new2value&new3=#thisanchor", + newUrl); + + } + + /** + * test for addParameterMap(). + */ + public final void testAddParameterMapMultiValue() + { + String url = "http://www.displaytag.org/displaytag/index.jsp"; + Href href = new DefaultHref(url); + + Map parameterMap = new HashMap(); + parameterMap.put("param1", new String[]{"à", "<"}); + href.addParameterMap(parameterMap); + + String newUrl = href.toString(); + assertEquals("http://www.displaytag.org/displaytag/index.jsp?param1=à&param1=<", newUrl); + + } + + /** + * test for addParameterMap() with overriding parameters. + */ + public final void testAddParameterMapOverridingParameters() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=original#thisanchor"; + Href href = new DefaultHref(url); + + Map parameterMap = new HashMap(); + parameterMap.put("param1", "original"); + parameterMap.put("new1", "new1value"); + href.addParameterMap(parameterMap); + + String newUrl = href.toString(); + URLAssert.assertEquals( + "http://www.displaytag.org/displaytag/index.jsp?param1=original&new1=new1value#thisanchor", + newUrl); + + } + + /** + * test for base url extraction. + */ + public final void testGetBaseUrl() + { + String url = "http://www.displaytag.org/displaytag/index.jsp?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + assertEquals(href.getBaseUrl(), "http://www.displaytag.org/displaytag/index.jsp"); + } + + /** + * Complex test. + */ + public final void testComplex() + { + String url = "http://www.displaytag.org/EProcurement/do/searchWorkflowAction?initiator=AVINASH&wfid=" + + "&approvedTDate=&initiatedFDate=&status=default&d-3824-p=2&initiatedTDate=04/28/2004" + + "&approvedFDate=&method=search&approver="; + Href href = new DefaultHref(url); + String newUrl = href.toString(); + URLAssert.assertEquals(url, newUrl); + } + + /** + * test for url without base. + */ + public final void testNoBaseUrl() + { + String url = "?param1=1¶m2=2#thisanchor"; + Href href = new DefaultHref(url); + assertEquals(href.getBaseUrl(), ""); + URLAssert.assertEquals(url, href.toString()); + } + +}