Simplify implementation:

* No need to use reflection because we always have JDK 1.4 functionality. 
* Use java.util.BitSet for lookup of URI-safe characters.
This commit is contained in:
hns 2007-10-03 14:43:39 +00:00
parent 9b75760568
commit 2fa6005ee1

View file

@ -17,10 +17,9 @@
package helma.util; package helma.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.BitSet;
/** /**
* A proxy to java.net.URLEncoder which only encodes when there is actual work * A proxy to java.net.URLEncoder which only encodes when there is actual work
@ -29,41 +28,36 @@ import java.net.URLEncoder;
* don't need encoding. * don't need encoding.
*/ */
public final class UrlEncoded { public final class UrlEncoded {
// Java 1.4 encode method to use instead of deprecated 1.3 version.
private static Method encode = null;
private static Method decode = null;
// Initialize the encode and decode variables with the 1.4 methods if static BitSet dontNeedEncoding;
// available.
// this code was adapted from org.apache.struts.utils.RequestUtils and
// org.apache.velocity.tools.view.tools.LinkTool
static { static {
try { dontNeedEncoding = new BitSet(256);
// get version of encode method with two String args int i;
Class[] args = new Class[] { String.class, String.class }; for (i = 'a'; i <= 'z'; i++)
encode = URLEncoder.class.getMethod("encode", args); dontNeedEncoding.set(i);
decode = URLDecoder.class.getMethod("decode", args); for (i = 'A'; i <= 'Z'; i++)
} catch (NoSuchMethodException e) { dontNeedEncoding.set(i);
System.err.println("UrlEncoded: Can't find JDK 1.4 encode and decode methods. Using JDK 1.3 versions."); for (i = '0'; i <= '9'; i++)
} dontNeedEncoding.set(i);
dontNeedEncoding.set(' '); // encoded separately
dontNeedEncoding.set('-');
dontNeedEncoding.set('_');
dontNeedEncoding.set('.');
dontNeedEncoding.set('*');
} }
/** /**
* URL-encodes a string using the given encoding, or return it unchanged if * URL-encodes a string using the given encoding, or return it unchanged if
* no encoding was necessary. * no encoding was necessary.
* This method uses the new URLEncoder.encode() method from java 1.4 if *
* available, otherwise the old deprecated version is used. Reflection is
* used to find the appropriate method; if the reflection operations throw
* exceptions other than UnsupportedEncodingException, it returns the url
* encoded with the old URLEncoder.encode() method.
*
* @param str The string to be URL-encoded * @param str The string to be URL-encoded
* @param encoding the encoding to use * @param encoding the encoding to use
* @return the URL-encoded string, or str if no encoding necessary * @return the URL-encoded string, or str if no encoding necessary
* @throws UnsupportedEncodingException encoding is not supported
*/ */
public static String encode(String str, String encoding) public static String encode(String str, String encoding)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
int l = str.length(); int l = str.length();
boolean needsSpaceEncoding = false; boolean needsSpaceEncoding = false;
@ -72,26 +66,8 @@ public final class UrlEncoded {
if (c == ' ') { if (c == ' ') {
needsSpaceEncoding = true; needsSpaceEncoding = true;
} else if (!(((c >= 'a') && (c <= 'z')) } else if (!dontNeedEncoding.get(c)) {
|| ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')))) { return URLEncoder.encode(str, encoding);
if (encode != null) {
try {
return (String) encode.invoke(null, new Object[] { str,
encoding });
} catch (IllegalAccessException e) {
// don't keep trying if we get one of these
encode = null;
System.err.println("UrlEncoded: Can't access JDK 1.4 encode method ("
+ e + "). Using deprecated version from now on.");
} catch (InvocationTargetException e) {
// this can only be a UnsupportedEncodingException:
Throwable ex = e.getTargetException();
if (ex instanceof UnsupportedEncodingException)
throw (UnsupportedEncodingException) ex;
}
}
return URLEncoder.encode(str);
} }
} }
@ -105,39 +81,18 @@ public final class UrlEncoded {
/** /**
* URL-decode a string using the given encoding, or return it unchanged if * URL-decode a string using the given encoding, or return it unchanged if
* no encoding was necessary. * no encoding was necessary.
* This method uses the new URLDecoder.decode() method from java 1.4 if
* available, otherwise the old deprecated version is used. Reflection is
* used to find the appropriate method; if the reflection operations throw
* exceptions other than UnsupportedEncodingException, it returns the url
* decoded with the old URLDecoder.decode() method.
* *
* @param str The string to be URL-decoded * @param str The string to be URL-decoded
* @param encoding the encoding to use * @param encoding the encoding to use
* @return the URL-decoded string, or str if no decoding necessary * @return the URL-decoded string, or str if no decoding necessary
* @throws UnsupportedEncodingException encoding is not supported
*/ */
public static String decode(String str, String encoding) public static String decode(String str, String encoding)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
if ((str.indexOf('+') == -1) && (str.indexOf('%') == -1)) { if ((str.indexOf('+') == -1) && (str.indexOf('%') == -1)) {
return str; return str;
} else { } else {
if (decode != null) { return URLDecoder.decode(str, encoding);
try {
return (String) decode.invoke(null, new Object[] { str,
encoding });
} catch (IllegalAccessException e) {
// don't keep trying if we get one of these
decode = null;
System.err.println("UrlEncoded: Can't access JDK 1.4 decode method ("
+ e + "). Using deprecated version from now on.");
} catch (InvocationTargetException e) {
// this can only be a UnsupportedEncodingException:
Throwable ex = e.getTargetException();
if (ex instanceof UnsupportedEncodingException)
throw (UnsupportedEncodingException) ex;
}
}
return URLDecoder.decode(str);
} }
} }