package org.jorgecardoso.net;
import java.io.*;
/**
* Utility class for HTML form encoding. This class contains static methods
* for converting a String to the application/x-www-form-urlencoded MIME
* format. For more information about HTML form encoding, consult the HTML
* specification.
*
*
* When encoding a String, the following rules apply: * *
*
a" through
* "z", "A" through
* "Z" and "0"
* through "9" remain the same.
* .",
* "-", "*", and
* "_" remain the same.
* " is
* converted into a plus sign "+".
* %xy", where xy is the
* two-digit hexadecimal representation of the byte.
* The recommended encoding scheme to use is UTF-8. However,
* for compatibility reasons, if an encoding is not specified,
* then the default encoding of the platform is used.
*
* @author Jorge Cardoso
* @version 1.00, 16/07/2005
*/
public class URLEncoder {
/**
* Encodes an already formed URL using the application/x-www-form-urlencoded
* MIME format.
*
* @param s The String (URL) to be converted.
*
* @return The converted String (URL).
*/
public static String URLEncode(String s) {
int questionMark = s.indexOf('?');
if (questionMark == -1) { // no parameters
return s;
} else {
return s.substring(0, questionMark+1) + encodeURL(s.substring(questionMark+1));
}
}
/**
* Base on code in http://forums.java.sun.com/thread.jspa?threadID=409913&messageID=1806947
* Converts a String to the application/x-www-form-urlencoded MIME
* format.
*
* @param s The String to be converted.
*
* @return The converted String.
*/
public static String encode(String s) {
StringBuffer out = new StringBuffer();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(bOut);
try {
dOut.writeUTF(s);
} catch (IOException ioe) {
return null;
}
ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
/* UTF strings have 2 bytes to indicate the size, so skip these */
bIn.read();
bIn.read();
int c = bIn.read();
while (c >= 0) {
if ((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| c == '.' || c == '-' || c == '*' || c == '_') {
out.append((char) c);
} else if (c == ' ') {
out.append('+');
} else {
if (c < 128) {
appendHex(c,out);
} else if (c < 224) {
appendHex(c,out);
appendHex(bIn.read(),out);
} else if (c < 240) {
appendHex(c,out);
appendHex(bIn.read(),out);
appendHex(bIn.read(),out);
}
}
c = bIn.read();
}
return out.toString();
}
/**
* Base on code in http://forums.java.sun.com/thread.jspa?threadID=409913&messageID=1806947
*
* Similar to encode but we don't encode the '=' and '&' characters. This
* way we can use this to encode an already formed URL (or better, the parameter
* part of an already formed URL).
*/
private static String encodeURL(String s) {
StringBuffer out = new StringBuffer();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DataOutputStream dOut = new DataOutputStream(bOut);
try {
dOut.writeUTF(s);
} catch (IOException ioe) {
return null;
}
ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
/* UTF strings have 2 bytes to indicate the size, so skip these */
bIn.read();
bIn.read();
int c = bIn.read();
while (c >= 0) {
if ((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| c == '.' || c == '-'
|| c == '*' || c == '_'
|| c == '=' || c == '&') {
out.append((char) c);
} else if (c == ' ') {
out.append('+');
} else {
if (c < 128) {
appendHex(c,out);
} else if (c < 224) {
appendHex(c,out);
appendHex(bIn.read(),out);
} else if (c < 240) {
appendHex(c,out);
appendHex(bIn.read(),out);
appendHex(bIn.read(),out);
}
}
c = bIn.read();
}
return out.toString();
}
private static void appendHex(int arg0, StringBuffer buff){
buff.append('%');
if (arg0<16) {
buff.append('0');
}
buff.append(Integer.toHexString(arg0));
}
}