Skip to content

Commit

Permalink
set ParamManager and UrlParam to deprecated in favor of UrlParamCodec…
Browse files Browse the repository at this point in the history
…, which feels like a better design
  • Loading branch information
Harald Kirsch committed Oct 11, 2015
1 parent 6b4423c commit 5c20fa0
Show file tree
Hide file tree
Showing 7 changed files with 393 additions and 10 deletions.
9 changes: 6 additions & 3 deletions build.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="htmlJgen" default="jar">

<property name="version" value="1.4.0"/>


<!--
Run 'ant ivy' first to download dependencies.
Expand All @@ -9,13 +12,13 @@
http://central.maven.org/maven2/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
-->

<!-- set cobertura.libdir in your .ant.properties file -->
<!-- Set cobertura.libdir in your .ant.properties file. If you don't
want to run the test coverage, you don't need this.
-->
<loadproperties srcFile="${user.home}/.ant.properties"/>
<include file="src/ant-macros/cobertura.xml"/>
<include file="src/ant-macros/javac.xml"/>

<property name="version" value="1.3.1-pre"/>

<path id="compile-classpath">
<fileset dir="libs/build" includes="**/*.jar"/>
</path>
Expand Down
8 changes: 8 additions & 0 deletions src/java/de/pifpafpuf/web/urlparam/ParamManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
/**
* helps to manage url query parameters by retrieving them from a request and
* by providing them again for a url.
*
* @deprecated The idea of a central manager for all URL parameters proved
* not to be too helpful. Rather define {@code static final}
* {@link UrlParamCodec} objects in the servlets that use the
* parameters and access the object in other servlets that
* generate the a parameter of this name and type into a URL or a
* form element.
*/
@Deprecated
public class ParamManager {

private final List<UrlParam<?>> params = new LinkedList<UrlParam<?>>();
Expand Down
24 changes: 19 additions & 5 deletions src/java/de/pifpafpuf/web/urlparam/UrlParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@
import javax.servlet.ServletRequest;

/**
* <p>describes a single value URL parameter of the given {@code TYPE}. Objects
* <p>
* describes a single value URL parameter of the given {@code TYPE}. Objects
* of this class are immutable, but may be used as builders for objects for
* the same {@code TYPE} but with another value. Objects of this type are
* used to fetch parameters from the {@link javax.servlet.ServletRequest} as
* well as to write the parameter with its value into a URL or an HTML form
* element.</p>
* <p>Example use of an <code>int</code> parameter.</p>
* <pre> // define the template
* element.
* </p>
* <p>
* Example use of an <code>int</code> parameter.
* </p>
*
* <pre>
* // define the template
* private static final UrlParam<Integer> P_COUNT =
* new UrlParam<Integer>("count", 0, new IntegerCodec(0, 10));
* ...
Expand All @@ -29,9 +35,17 @@
* new Html("input").setAttr("type", "text")
* .setAttr("name", newCount.getName())
* .setAttr("value", newCount.getForInputParam()));
* </pre.
* </pre
*
* .
*
* @deprecated The design of combining encoding/decoding of parameters with a
* (default) value proved to be strange in use. Instead use
* {@code static final} {@link UrlParamCodec} objects and provide
* default values on the fly when using its methods.
* @param <TYPE> is the type of the parameter stored.
*/
@Deprecated
public class UrlParam<TYPE> {
private final String name;
private final TYPE value;
Expand Down
211 changes: 211 additions & 0 deletions src/java/de/pifpafpuf/web/urlparam/UrlParamCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package de.pifpafpuf.web.urlparam;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletRequest;

import de.pifpafpuf.web.html.EmptyElem;
import de.pifpafpuf.web.urlparam.ParamCodec;

/**
* <p>
* decodes and encodes parameter values of type {@code TYPE} from URLs
* and for HTML forms and links.</p>
*
* <p>Objects of this class are immutable. They are used to fetch parameters
* from the {@link javax.servlet.ServletRequest} as well as to write the
* parameter with its value into a URL or an HTML form element.
* </p>
*
* @param <TYPE> is the type of the parameter stored.
*/
public class UrlParamCodec<TYPE> {
private final String name;
private final ParamCodec<TYPE> paramCodec;

/**
* creates a url parameter codec for a parameter with the given name and
* type.
*
* @param name of the parameter as used in the URL. No check is made
* whether the name conforms to the syntax rules of URL parameter
* names and no encoding/decoding is performed for the name.
* @param codec is the codec to decode strings retrieved from
* {@link javax.servlet.ServletRequest} and to encode the value for
* a URL or an HTML form input element. The codec should only
* encode/decode to/from an arbitrary <code>String</code> URL
* en/decoding is taken care of by {@code this}.
*/
public UrlParamCodec(String name, ParamCodec<TYPE> codec) {
if (name==null) {
throw new NullPointerException("parameter name may not be null");
}
this.name = name;
if (codec==null) {
throw new NullPointerException("parameter pp may not be null");
}
this.paramCodec = codec;
}
/*+******************************************************************/
public String getName() {
return name;
}
/*+******************************************************************/
/**
* returns the value encoded in string form by the codec defined in the
* constructor. No HTML or URL encoding is performed.
*/
public String asString(TYPE value) {
return paramCodec.asString(value);
}
/**
* sets the name and the value attribute in the given {@code html} element
* to reflect this
*
* @param html
*/
public void setParam(EmptyElem html, TYPE value) {
html.setAttr("name", name);
html.setAttr("value", paramCodec.asString(value));
}
/*+**********************************************************************/
/**
* returns the value of <code>this</code> after first encoding it with our
* codec and then URL-encoding it.
*/
public String getForUrlParam(TYPE value) {
return encodeForUrl(paramCodec.asString(value));
}
/*+**********************************************************************/
/**
* appends the encoded {@code value} to the
* {@link java.util.StringBuilder} provided. If the URL provided does not
* end with a '?', the parameter is prefixed with '&'.
*/
public void appendToUrl(StringBuilder sb, TYPE value) {
final int l = sb.length();
if (l==0 || sb.charAt(l-1)!='?') {
sb.append('&');
}
sb.append(name).append('=').append(getForUrlParam(value));
}
/*+******************************************************************/
/**
* creates a {@code TYPE} from the given text. If the text is
* cannot be parsed by the codec, the {@code defaultValue} is
* returned.
*
* @param text to be converted, may be {@code null}
* @return a new object or the default value
*/
public TYPE fromString(String text, TYPE defaultValue) {
TYPE v = paramCodec.get(text);
if (v==null) {
return defaultValue;
}
return v;
}
/*+******************************************************************/
/**
* <p>
* creates a {@code TYPE} from the value returned by
* <code>req.getParameter</code> by calling {@link #fromString}.
* </p>
*
* @param req where to get the parameter value from, may not be
* <code>null</code>
*/
public TYPE fromFirst(ServletRequest req, TYPE defaultValue) {
String text = req.getParameter(name);
return fromString(text, defaultValue);
}
/*+******************************************************************/
/**
* <p>
* creates a list of {@code TYPE} objects from all values returned by
* <code>req.getParameterValues()</code> by calling {@link #fromString} for
* each of them. If the request parameter does not exist or
* <code>ServletRequest.getParameterValues</code> returns an empty array
* (no idea whether this may happen at all), a list of length zero is
* returned. If an individual parameter value cannot be parsed, it is
* skipped.
* </p>
*
* @param req where to get the parameter values from, may not be
* <code>null</code>
*/
public List<TYPE> fromAll(ServletRequest req) {
String[] values = req.getParameterValues(name);
if (values==null) {
return new LinkedList<TYPE>();
}
List<TYPE> result = new ArrayList<TYPE>(values.length);
for(String value : values) {
TYPE v = fromString(value, null);
if (v!=null) {
result.add(v);
}
}
return result;
}
/*+******************************************************************/
// TODO: according to several stackoverflow comments, URLEncoder is not
// exactly the right way to do this. (A) it is slow, (B) it is for form
// encoding (what the browser does, when POSTing a form). But looking at
// the suggested java.net.URI, this is even more hideous, as it first
// creates a string and then parses it (ouch). So, how's the encoding done
// right? Caveat: I would like to not introduce a dependency to Spring or
// some Apache library.
private static String encodeForUrl(String text) {
try {
return URLEncoder.encode(text, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("this should not happen, "+
"why don't we have UTF-8?", e);
}
}
/*+******************************************************************/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime*result+(name.hashCode());
result = prime*result+(paramCodec.hashCode());
return result;
}
/*+******************************************************************/
@Override
public boolean equals(Object obj) {
if( this==obj ) {
return true;
}
if( obj==null ) {
return false;
}
if( getClass()!=obj.getClass() ) {
return false;
}

@SuppressWarnings("rawtypes")
UrlParamCodec other = (UrlParamCodec)obj;
if (!name.equals(other.name) ) {
return false;
}

if (!paramCodec.equals(other.paramCodec)) {
return false;
}

return true;
}
/*+******************************************************************/
@Override
public String toString() {
return name+"=("+paramCodec.getClass().getName()+")";
}
}

2 changes: 1 addition & 1 deletion src/java/overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ <h1>Usage Hints</h1>
<ol>
<li>Create an HTML structure with classes from {@link de.pifpafpuf.web.html}.</li>
<li>Manage your URL parameters with {@link
de.pifpafpuf.web.urlparam.UrlParam}.
de.pifpafpuf.web.urlparam.UrlParamCodec}.
</ol>

</body>
2 changes: 1 addition & 1 deletion test/src/java/de/pifpafpuf/HtmlPageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class HtmlPageTest {
@Test
public void pageBasicTest() throws IOException {
HtmlPage page = new HtmlPage("a title for the page");
String expected = "<!doctype html>\n" +
String expected = "<!DOCTYPE html>\n" +
"<html>\n"+
" <head>\n"+
" <title>a title for the page</title>\n"+
Expand Down
Loading

0 comments on commit 5c20fa0

Please sign in to comment.