Clover coverage report - Maven Clover report
Coverage timestamp: Wed Aug 15 2007 21:58:57 GMT+01:00
file stats: LOC: 398   Methods: 15
NCLOC: 241   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultHref.java 93.8% 93% 80% 92%
coverage coverage
 1    /**
 2    * Licensed under the Artistic License; you may not use this file
 3    * except in compliance with the License.
 4    * You may obtain a copy of the License at
 5    *
 6    * http://displaytag.sourceforge.net/license.html
 7    *
 8    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
 9    * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 10    * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 11    */
 12    package org.displaytag.util;
 13   
 14    import java.util.HashMap;
 15    import java.util.Iterator;
 16    import java.util.Map;
 17    import java.util.Set;
 18    import java.util.StringTokenizer;
 19   
 20    import org.apache.commons.lang.ObjectUtils;
 21    import org.apache.commons.lang.StringEscapeUtils;
 22    import org.apache.commons.lang.StringUtils;
 23    import org.apache.commons.lang.UnhandledException;
 24    import org.apache.commons.lang.builder.EqualsBuilder;
 25    import org.apache.commons.lang.builder.HashCodeBuilder;
 26   
 27   
 28    /**
 29    * @author Fabrizio Giustina
 30    * @version $Revision$ ($Author$)
 31    */
 32    public class DefaultHref implements Href
 33    {
 34   
 35    /**
 36    * D1597A17A6.
 37    */
 38    private static final long serialVersionUID = 899149338534L;
 39   
 40    /**
 41    * Base url for the href.
 42    */
 43    private String url;
 44   
 45    /**
 46    * Url parameters.
 47    */
 48    private Map parameters;
 49   
 50    /**
 51    * Anchor (to be added at the end of URL).
 52    */
 53    private String anchor;
 54   
 55    /**
 56    * Construct a new Href parsing a URL. Parameters are stripped from the base url and saved in the parameters map.
 57    * @param baseUrl String
 58    */
 59  451 public DefaultHref(String baseUrl)
 60    {
 61  451 this.parameters = new HashMap();
 62  451 setFullUrl(baseUrl);
 63    }
 64   
 65    /**
 66    * @see org.displaytag.util.Href#setFullUrl(java.lang.String)
 67    */
 68  471 public void setFullUrl(String baseUrl)
 69    {
 70  471 this.url = null;
 71  471 this.anchor = null;
 72  471 String noAnchorUrl;
 73  471 int anchorposition = baseUrl.indexOf('#');
 74   
 75    // extract anchor from url
 76  471 if (anchorposition != -1)
 77    {
 78  13 noAnchorUrl = baseUrl.substring(0, anchorposition);
 79  13 this.anchor = baseUrl.substring(anchorposition + 1);
 80    }
 81    else
 82    {
 83  458 noAnchorUrl = baseUrl;
 84    }
 85   
 86  471 if (noAnchorUrl.indexOf('?') == -1)
 87    {
 88    // simple url, no parameters
 89  448 this.url = noAnchorUrl;
 90  448 return;
 91    }
 92   
 93    // the Url already has parameters, put them in the parameter Map
 94  23 StringTokenizer tokenizer = new StringTokenizer(noAnchorUrl, "?"); //$NON-NLS-1$
 95   
 96  23 if (baseUrl.startsWith("?")) //$NON-NLS-1$
 97    {
 98    // support fake URI's which are just parameters to use with the current uri
 99  3 url = TagConstants.EMPTY_STRING;
 100    }
 101    else
 102    {
 103    // base url (before "?")
 104  20 url = tokenizer.nextToken();
 105    }
 106   
 107  23 if (!tokenizer.hasMoreTokens())
 108    {
 109  0 return;
 110    }
 111   
 112    // process parameters
 113  23 StringTokenizer paramTokenizer = new StringTokenizer(tokenizer.nextToken(), "&"); //$NON-NLS-1$
 114   
 115    // split parameters (key=value)
 116  23 while (paramTokenizer.hasMoreTokens())
 117    {
 118    // split key and value ...
 119  47 String[] keyValue = StringUtils.split(paramTokenizer.nextToken(), '=');
 120   
 121    // encode name/value to prevent css
 122  47 String escapedKey = StringEscapeUtils.escapeHtml(keyValue[0]);
 123  47 String escapedValue = keyValue.length > 1
 124    ? StringEscapeUtils.escapeHtml(keyValue[1])
 125    : TagConstants.EMPTY_STRING;
 126   
 127  47 if (!this.parameters.containsKey(escapedKey))
 128    {
 129    // ... and add it to the map
 130  44 this.parameters.put(escapedKey, escapedValue);
 131    }
 132    else
 133    {
 134    // additional value for an existing parameter
 135  3 Object previousValue = this.parameters.get(escapedKey);
 136  3 if (previousValue != null && previousValue.getClass().isArray())
 137    {
 138  2 Object[] previousArray = (Object[]) previousValue;
 139  2 Object[] newArray = new Object[previousArray.length + 1];
 140   
 141  2 int j;
 142   
 143  2 for (j = 0; j < previousArray.length; j++)
 144    {
 145  5 newArray[j] = previousArray[j];
 146    }
 147   
 148  2 newArray[j] = escapedValue;
 149  2 this.parameters.put(escapedKey, newArray);
 150    }
 151    else
 152    {
 153  1 this.parameters.put(escapedKey, new Object[]{previousValue, escapedValue});
 154    }
 155    }
 156    }
 157    }
 158   
 159    /**
 160    * Adds a parameter to the href.
 161    * @param name String
 162    * @param value Object
 163    * @return this Href instance, useful for concatenation.
 164    */
 165  828 public Href addParameter(String name, Object value)
 166    {
 167  828 this.parameters.put(name, ObjectUtils.toString(value, null));
 168  828 return this;
 169    }
 170   
 171    /**
 172    * Removes a parameter from the href.
 173    * @param name String
 174    */
 175  12 public void removeParameter(String name)
 176    {
 177    // warning, param names are escaped
 178  12 this.parameters.remove(StringEscapeUtils.escapeHtml(name));
 179    }
 180   
 181    /**
 182    * Adds an int parameter to the href.
 183    * @param name String
 184    * @param value int
 185    * @return this Href instance, useful for concatenation.
 186    */
 187  487 public Href addParameter(String name, int value)
 188    {
 189  487 this.parameters.put(name, new Integer(value));
 190  487 return this;
 191    }
 192   
 193    /**
 194    * Getter for the map containing link parameters. The returned map is always a copy and not the original instance.
 195    * @return parameter Map (copy)
 196    */
 197  4 public Map getParameterMap()
 198    {
 199  4 Map copyMap = new HashMap(this.parameters.size());
 200  4 copyMap.putAll(this.parameters);
 201  4 return copyMap;
 202    }
 203   
 204    /**
 205    * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before
 206    * added. Any parameter already present in the href object is removed.
 207    * @param parametersMap Map containing parameters
 208    */
 209  405 public void setParameterMap(Map parametersMap)
 210    {
 211    // create a new HashMap
 212  405 this.parameters = new HashMap(parametersMap.size());
 213   
 214    // copy the parameters
 215  405 addParameterMap(parametersMap);
 216    }
 217   
 218    /**
 219    * Adds all the parameters contained in the map to the Href. The value in the given Map will be escaped before
 220    * added. Parameters in the original href are kept and not overridden.
 221    * @param parametersMap Map containing parameters
 222    */
 223  408 public void addParameterMap(Map parametersMap)
 224    {
 225    // handle nulls
 226  408 if (parametersMap == null)
 227    {
 228  0 return;
 229    }
 230   
 231    // copy value, escaping html
 232  408 Iterator mapIterator = parametersMap.entrySet().iterator();
 233  408 while (mapIterator.hasNext())
 234    {
 235  371 Map.Entry entry = (Map.Entry) mapIterator.next();
 236  371 String key = StringEscapeUtils.escapeHtml((String) entry.getKey());
 237   
 238    // don't overwrite parameters
 239  371 if (!this.parameters.containsKey(key))
 240    {
 241  370 Object value = entry.getValue();
 242   
 243  370 if (value != null)
 244    {
 245  368 if (value.getClass().isArray())
 246    {
 247  363 String[] values = (String[]) value;
 248  363 for (int i = 0; i < values.length; i++)
 249    {
 250  364 values[i] = StringEscapeUtils.escapeHtml(values[i]);
 251    }
 252    }
 253    else
 254    {
 255  5 value = StringEscapeUtils.escapeHtml(value.toString());
 256    }
 257    }
 258   
 259  370 this.parameters.put(key, value);
 260    }
 261    }
 262    }
 263   
 264    /**
 265    * Getter for the base url (without parameters).
 266    * @return String
 267    */
 268  26 public String getBaseUrl()
 269    {
 270  26 return this.url;
 271    }
 272   
 273    /**
 274    * Returns the URI anchor.
 275    * @return anchor or <code>null</code> if no anchor has been set.
 276    */
 277  0 public String getAnchor()
 278    {
 279  0 return this.anchor;
 280    }
 281   
 282    /**
 283    * Setter for the URI anchor.
 284    * @param name string to be used as anchor name (without #).
 285    */
 286  0 public void setAnchor(String name)
 287    {
 288  0 this.anchor = name;
 289    }
 290   
 291    /**
 292    * toString: output the full url with parameters.
 293    * @return String
 294    */
 295  792 public String toString()
 296    {
 297  792 StringBuffer buffer = new StringBuffer(30);
 298   
 299  792 buffer.append(this.url);
 300   
 301  792 if (this.parameters.size() > 0)
 302    {
 303  786 buffer.append('?');
 304  786 Set parameterSet = this.parameters.entrySet();
 305   
 306  786 Iterator iterator = parameterSet.iterator();
 307   
 308  786 while (iterator.hasNext())
 309    {
 310  2254 Map.Entry entry = (Map.Entry) iterator.next();
 311   
 312  2254 Object key = entry.getKey();
 313  2254 Object value = entry.getValue();
 314   
 315  2254 if (value == null)
 316    {
 317  2 buffer.append(key).append('='); // no value
 318    }
 319  2252 else if (value.getClass().isArray())
 320    {
 321  1116 Object[] values = (Object[]) value;
 322  1116 for (int i = 0; i < values.length; i++)
 323    {
 324  1120 if (i > 0)
 325    {
 326  4 buffer.append(TagConstants.AMPERSAND);
 327    }
 328   
 329  1120 buffer.append(key).append('=').append(values[i]);
 330    }
 331    }
 332    else
 333    {
 334  1136 buffer.append(key).append('=').append(value);
 335    }
 336   
 337  2254 if (iterator.hasNext())
 338    {
 339  1468 buffer.append(TagConstants.AMPERSAND);
 340    }
 341    }
 342    }
 343   
 344  792 if (this.anchor != null)
 345    {
 346  10 buffer.append('#');
 347  10 buffer.append(this.anchor);
 348    }
 349   
 350  792 return buffer.toString();
 351    }
 352   
 353    /**
 354    * @see java.lang.Object#clone()
 355    */
 356  1068 public Object clone()
 357    {
 358  1068 final DefaultHref href;
 359  1068 try
 360    {
 361  1068 href = (DefaultHref) super.clone();
 362    }
 363    catch (CloneNotSupportedException e)
 364    {
 365  0 throw new UnhandledException(e);
 366    }
 367   
 368  1068 href.parameters = new HashMap(this.parameters);
 369  1068 return href;
 370    }
 371   
 372    /**
 373    * @see java.lang.Object#equals(Object)
 374    */
 375  3 public boolean equals(Object object)
 376    {
 377  3 if (!(object instanceof DefaultHref))
 378    {
 379  0 return false;
 380    }
 381  3 DefaultHref rhs = (DefaultHref) object;
 382  3 return new EqualsBuilder().append(this.parameters, rhs.parameters).append(this.url, rhs.url).append(
 383    this.anchor,
 384    rhs.anchor).isEquals();
 385    }
 386   
 387    /**
 388    * @see java.lang.Object#hashCode()
 389    */
 390  0 public int hashCode()
 391    {
 392  0 return new HashCodeBuilder(1313733113, -431360889)
 393    .append(this.parameters)
 394    .append(this.url)
 395    .append(this.anchor)
 396    .toHashCode();
 397    }
 398    }