I18NParseUtilpublic final class I18NParseUtil extends Object Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
All rights reserved. |
Fields Summary |
---|
public static final Logger | _loggerThe logger to use for logging info about the charset
found from hidden field or locale-charset-map | private static boolean | _debugLogThis indicates whether debug logging is on or not |
Methods Summary |
---|
private static byte | convertHexDigit(byte b)Convert a byte character value to hexidecimal digit value.
if ((b >= '0") && (b <= '9")) return (byte)(b - '0");
if ((b >= 'a") && (b <= 'f")) return (byte)(b - 'a" + 10);
if ((b >= 'A") && (b <= 'F")) return (byte)(b - 'A" + 10);
return 0;
| public static java.lang.String | getLocaleCharsetEncoding(javax.servlet.http.HttpServletRequest request, com.sun.enterprise.deployment.runtime.web.LocaleCharsetMap[] charsetMap)Return the charset corresponding to a (locale, agent) pair.
IMPLEMENTATION NOTE: The lcMap parameter contains
an array of LocaleCharsetMap object. A LocaleCharsetMap object consist
of (locale, agent, charset). The agent attribute may be a null value.
If agent is null, we match the locale attribute to the requst locale.
If agent is not null we match (locale, agent) to the request locale,
and request agent header value. We look for exact match of the agent,
so it is the user responsibility to give and exact value of the agent
in ias-web XML file. If no match is found, ISO-8859-1 is returned.
if (charsetMap == null)
return null;
String requestLocale = request.getLocale().toString();
if (requestLocale == null)
return null;
String userAgent = request.getHeader("user-agent");
for (int i = 0; i < charsetMap.length; i++) {
LocaleCharsetMap element = charsetMap[i];
String s = (String)element.getAttributeValue("Locale");
if (s.equals(requestLocale)) {
String agent = (String)element.getAttributeValue("Agent");
if (agent == null || agent.length() == 0 ||
userAgent == null || agent.equals(userAgent)) {
String encoding =
(String)element.getAttributeValue("Charset");
if (_debugLog)
_logger.fine("Got charset in locale-charset-map" +
", locale=" + requestLocale +
", agent=" + agent +
", charset=" + encoding);
return encoding;
}
}
}
return null;
| public static java.lang.String | parseParametersUsingLCInfo(java.util.Map map, java.lang.String queryString, byte[] buf, com.sun.enterprise.deployment.runtime.web.LocaleCharsetMap[] lcMap, java.lang.String hiddenFieldName, javax.servlet.http.HttpServletRequest request)Parse the request parameter according to the locale-charset-info tag
in ias-web.xml
IMPLEMENTATION NOTE: If hiddenFieldName is null,
get the encoding from lcMap object, and let the original
RequestUtil.parseParameters deal with the parsing. If hiddenFieldName
is not null, first prase queryString to get hidden field value.
if hidden field value is found in the queryString, then buf parsing
will be handled by RequestUtil.parseParameters according to that value.
If hidden field value is not found in queryString, then save the
query string keys in a linked list and look for a hidden field value
in buf. Once the hidden field value is found in buf, process
the linked list of queryString according to that value.
If hidden field value not found in buf either, get encoding value
from lcMap. If none is found, then default to ISO-8859-1.
Then process both linked list objects.
NOTE: byte array buf is modified by this method. Caller beware.
byte[] queryStringBytes = null;
if ((queryString != null) && (queryString.length() > 0))
queryStringBytes = queryString.getBytes();
//process query string
LinkedList queryStringKeys = new LinkedList();
String hiddenFieldValue = processBufferWithHiddenField(
map, queryStringBytes, hiddenFieldName,
queryStringKeys, null, null);
//done with query String, process buf
//test if hidden field was found in query string
if (hiddenFieldValue != null) {
if (_debugLog)
_logger.fine("Got charset from queryString, hidden field " +
"name = " + hiddenFieldName + ", hidden field value = " +
hiddenFieldValue);
RequestUtil.parseParameters(map, buf, hiddenFieldValue);
return hiddenFieldValue;
}
// hidden field not found in query string, try to find it in POST data
LinkedList bufKeys = new LinkedList();
hiddenFieldValue = processBufferWithHiddenField(
map, buf, hiddenFieldName, bufKeys,
queryStringBytes, queryStringKeys);
if (hiddenFieldValue != null) {
if (_debugLog)
_logger.fine("Got charset from POST data, hidden field " +
"name = " + hiddenFieldName + ", hidden field value = " +
hiddenFieldValue);
return hiddenFieldValue;
}
String encoding = null;
if (lcMap != null) {
encoding = getLocaleCharsetEncoding(request, lcMap);
hiddenFieldValue = encoding;
}
if (encoding == null) {
encoding = "ISO-8859-1";
if (_debugLog)
_logger.fine("Using default encoding to parse params: " +
encoding);
}
processLinkedList(map, queryStringBytes, queryStringKeys, encoding);
processLinkedList(map, buf, bufKeys, encoding);
return hiddenFieldValue;
| public static java.lang.String | processBufferWithHiddenField(java.util.Map map, byte[] buf, java.lang.String hiddenFieldName, java.util.LinkedList keys, byte[] queryStringBytes, java.util.LinkedList queryStringKeys)Append request parameters from the specified String to the specified
Map. It is presumed that the specified Map is not accessed from any
other thread, so no synchronization is performed.
IMPLEMENTATION NOTE: We look for a hidden field value
in order to do URL decoding according it. While looking for that
hidden field, keys are stored in a linked list along with the start
and end pos of the correspondign value. This is done to avoid double
parsing. Once the hidden field is found, the linked list is processed
and parsing continues according to the already found hidden field value
Parsing is done individually on name and value elements, rather than on
the entire query string ahead of time, to properly deal with the case
where the name or value includes an encoded "=" or "&" character
that would otherwise be interpreted as a delimiter.
NOTE: byte array data is modified by this method. Caller beware.
int pos = 0;
int ix = 0;
int ox = 0;
String key = null;
String value = null;
boolean foundHiddenField = false;
String hiddenFieldValue = null;
if (buf == null)
return null;
while (ix < buf.length) {
byte c = buf[ix++];
switch ((char) c) {
case '&":
if (key != null) {
if (foundHiddenField) {
value = new String(buf, pos, ox - pos,
hiddenFieldValue);
putMapEntry(map, key, value);
}
else if (key.equals(hiddenFieldName)) {
hiddenFieldValue = new String(buf, pos, ox - pos,
"ISO-8859-1");
// hidden field found, process the linked lists that
// have been created so far
if (queryStringKeys != null)
processLinkedList(map, queryStringBytes,
queryStringKeys, hiddenFieldValue);
processLinkedList(map, buf, keys, hiddenFieldValue);
putMapEntry(map, key, hiddenFieldValue);
foundHiddenField = true;
}
else {
Object[] startEndPos = new Object[3];
startEndPos[0] = key;
startEndPos[1] = new Integer(pos);
startEndPos[2] = new Integer(ox);
keys.add(startEndPos);
}
key = null;
}
pos = ix;
ox = ix;
break;
case '=":
if (key == null) {
key = new String(buf, pos, ox - pos, "ISO-8859-1");
ox = ix;
pos = ix;
} else {
buf[ox++] = c;
}
break;
case '+":
buf[ox++] = (byte)' ";
break;
case '%":
buf[ox++] = (byte)((convertHexDigit(buf[ix++]) << 4) +
convertHexDigit(buf[ix++]));
break;
default:
buf[ox++] = c;
}
}
//The last value does not end in '&'. So save it now.
if (key != null) {
if (foundHiddenField) {
value = new String(buf, pos, ox - pos, hiddenFieldValue);
putMapEntry(map, key, value);
}
else if (key.equals(hiddenFieldName)) {
hiddenFieldValue = new String(buf, pos, ox - pos, "ISO-8859-1");
// hidden field found, process the linked lists that
// have been created so far
if (queryStringKeys != null)
processLinkedList(map, queryStringBytes, queryStringKeys,
hiddenFieldValue);
processLinkedList(map, buf, keys, hiddenFieldValue);
putMapEntry(map, key, hiddenFieldValue);
foundHiddenField = true;
}
else {
Object[] startEndPos = new Object[3];
startEndPos[0] = key;
startEndPos[1] = new Integer(pos);
startEndPos[2] = new Integer(ox);
keys.add(startEndPos);
}
}
return hiddenFieldValue;
| public static void | processLinkedList(java.util.Map map, byte[] buf, java.util.LinkedList keys, java.lang.String encoding)Process a linked list containing. The linked list nodes consist of
(key, start pos, end pos)
start pos and end pos correspond to the start and end postion of the
value corresponding to the key.
IMPLEMENTATION NOTE: Process the whole linked.
A key, value pair is created from each node and stored in the map.
if (buf == null || keys == null)
return;
ListIterator keysIterator = keys.listIterator(0);
while (keysIterator.hasNext()) {
Object[] startEndPos = (Object[])keysIterator.next();
String key = (String)startEndPos[0];
int startPos = ((Integer)startEndPos[1]).intValue();
int endPos = ((Integer)startEndPos[2]).intValue();
String value = new String(buf, startPos, endPos - startPos,
encoding);
putMapEntry(map, key, value);
}
keys.clear();
| private static void | putMapEntry(java.util.Map map, java.lang.String name, java.lang.String value)Put name value pair in map.
String[] newValues = null;
String[] oldValues = (String[]) map.get(name);
if (oldValues == null) {
newValues = new String[1];
newValues[0] = value;
} else {
newValues = new String[oldValues.length + 1];
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
newValues[oldValues.length] = value;
}
map.put(name, newValues);
|
|