1 23 24 29 30 package com.sun.enterprise.web.util; 31 32 import java.util.Map ; 33 import java.util.Locale ; 34 import java.util.LinkedList ; 35 import java.util.ListIterator ; 36 import java.util.logging.Logger ; 37 import java.util.logging.Level ; 38 import java.io.UnsupportedEncodingException ; 39 40 import javax.servlet.http.HttpServletRequest ; 41 42 import org.apache.catalina.util.RequestUtil; 43 import com.sun.enterprise.deployment.runtime.web.LocaleCharsetMap; 44 import com.sun.logging.LogDomains; 45 46 public final class I18NParseUtil { 47 48 52 public static Logger _logger = null; 53 54 57 private static boolean _debugLog; 58 59 static { 61 _logger = LogDomains.getLogger(LogDomains.WEB_LOGGER); 62 _debugLog = _logger.isLoggable(Level.FINE); 63 } 64 65 97 public static String parseParametersUsingLCInfo( 98 Map map, String queryString, byte[] buf, 99 LocaleCharsetMap[] lcMap, String hiddenFieldName, 100 HttpServletRequest request) 101 throws UnsupportedEncodingException { 102 103 byte[] queryStringBytes = null; 104 if ((queryString != null) && (queryString.length() > 0)) 105 queryStringBytes = queryString.getBytes(); 106 107 LinkedList queryStringKeys = new LinkedList (); 109 String hiddenFieldValue = processBufferWithHiddenField( 110 map, queryStringBytes, hiddenFieldName, 111 queryStringKeys, null, null); 112 if (hiddenFieldValue != null) { 115 if (_debugLog) 116 _logger.fine("Got charset from queryString, hidden field " + 117 "name = " + hiddenFieldName + ", hidden field value = " + 118 hiddenFieldValue); 119 RequestUtil.parseParameters(map, buf, hiddenFieldValue); 120 return hiddenFieldValue; 121 } 122 123 LinkedList bufKeys = new LinkedList (); 125 hiddenFieldValue = processBufferWithHiddenField( 126 map, buf, hiddenFieldName, bufKeys, 127 queryStringBytes, queryStringKeys); 128 129 if (hiddenFieldValue != null) { 130 if (_debugLog) 131 _logger.fine("Got charset from POST data, hidden field " + 132 "name = " + hiddenFieldName + ", hidden field value = " + 133 hiddenFieldValue); 134 return hiddenFieldValue; 135 } 136 137 String encoding = null; 138 if (lcMap != null) { 139 encoding = getLocaleCharsetEncoding(request, lcMap); 140 hiddenFieldValue = encoding; 141 } 142 143 if (encoding == null) { 144 encoding = "ISO-8859-1"; 145 if (_debugLog) 146 _logger.fine("Using default encoding to parse params: " + 147 encoding); 148 } 149 150 processLinkedList(map, queryStringBytes, queryStringKeys, encoding); 151 processLinkedList(map, buf, bufKeys, encoding); 152 153 return hiddenFieldValue; 154 } 155 156 182 public static String processBufferWithHiddenField( 183 Map map, byte[] buf, String hiddenFieldName, 184 LinkedList keys, byte[] queryStringBytes, 185 LinkedList queryStringKeys) 186 throws UnsupportedEncodingException { 187 188 int pos = 0; 189 int ix = 0; 190 int ox = 0; 191 String key = null; 192 String value = null; 193 boolean foundHiddenField = false; 194 String hiddenFieldValue = null; 195 196 if (buf == null) 197 return null; 198 199 while (ix < buf.length) { 200 byte c = buf[ix++]; 201 switch ((char) c) { 202 case '&': 203 if (key != null) { 204 if (foundHiddenField) { 205 value = new String (buf, pos, ox - pos, 206 hiddenFieldValue); 207 putMapEntry(map, key, value); 208 } 209 else if (key.equals(hiddenFieldName)) { 210 hiddenFieldValue = new String (buf, pos, ox - pos, 211 "ISO-8859-1"); 212 if (queryStringKeys != null) 215 processLinkedList(map, queryStringBytes, 216 queryStringKeys, hiddenFieldValue); 217 processLinkedList(map, buf, keys, hiddenFieldValue); 218 putMapEntry(map, key, hiddenFieldValue); 219 foundHiddenField = true; 220 } 221 else { 222 Object [] startEndPos = new Object [3]; 223 startEndPos[0] = key; 224 startEndPos[1] = new Integer (pos); 225 startEndPos[2] = new Integer (ox); 226 keys.add(startEndPos); 227 } 228 key = null; 229 } 230 pos = ix; 231 ox = ix; 232 break; 233 case '=': 234 if (key == null) { 235 key = new String (buf, pos, ox - pos, "ISO-8859-1"); 236 ox = ix; 237 pos = ix; 238 } else { 239 buf[ox++] = c; 240 } 241 break; 242 case '+': 243 buf[ox++] = (byte)' '; 244 break; 245 case '%': 246 buf[ox++] = (byte)((convertHexDigit(buf[ix++]) << 4) + 247 convertHexDigit(buf[ix++])); 248 break; 249 default: 250 buf[ox++] = c; 251 } 252 } 253 254 if (key != null) { 256 if (foundHiddenField) { 257 value = new String (buf, pos, ox - pos, hiddenFieldValue); 258 putMapEntry(map, key, value); 259 } 260 else if (key.equals(hiddenFieldName)) { 261 hiddenFieldValue = new String (buf, pos, ox - pos, "ISO-8859-1"); 262 if (queryStringKeys != null) 265 processLinkedList(map, queryStringBytes, queryStringKeys, 266 hiddenFieldValue); 267 processLinkedList(map, buf, keys, hiddenFieldValue); 268 putMapEntry(map, key, hiddenFieldValue); 269 foundHiddenField = true; 270 } 271 else { 272 Object [] startEndPos = new Object [3]; 273 startEndPos[0] = key; 274 startEndPos[1] = new Integer (pos); 275 startEndPos[2] = new Integer (ox); 276 keys.add(startEndPos); 277 } 278 } 279 280 return hiddenFieldValue; 281 } 282 283 299 public static void processLinkedList(Map map, byte[] buf, LinkedList keys, 300 String encoding) 301 throws UnsupportedEncodingException { 302 303 if (buf == null || keys == null) 304 return; 305 306 ListIterator keysIterator = keys.listIterator(0); 307 while (keysIterator.hasNext()) { 308 Object [] startEndPos = (Object [])keysIterator.next(); 309 String key = (String )startEndPos[0]; 310 int startPos = ((Integer )startEndPos[1]).intValue(); 311 int endPos = ((Integer )startEndPos[2]).intValue(); 312 String value = new String (buf, startPos, endPos - startPos, 313 encoding); 314 putMapEntry(map, key, value); 315 } 316 keys.clear(); 317 } 318 319 337 public static String getLocaleCharsetEncoding(HttpServletRequest request, 338 LocaleCharsetMap[] charsetMap) { 339 if (charsetMap == null) 340 return null; 341 342 String requestLocale = request.getLocale().toString(); 343 if (requestLocale == null) 344 return null; 345 346 String userAgent = request.getHeader("user-agent"); 347 348 for (int i = 0; i < charsetMap.length; i++) { 349 LocaleCharsetMap element = charsetMap[i]; 350 String s = (String )element.getAttributeValue("Locale"); 351 if (s.equals(requestLocale)) { 352 String agent = (String )element.getAttributeValue("Agent"); 353 if (agent == null || agent.length() == 0 || 354 userAgent == null || agent.equals(userAgent)) { 355 String encoding = 356 (String )element.getAttributeValue("Charset"); 357 if (_debugLog) 358 _logger.fine("Got charset in locale-charset-map" + 359 ", locale=" + requestLocale + 360 ", agent=" + agent + 361 ", charset=" + encoding); 362 return encoding; 363 } 364 } 365 } 366 return null; 367 } 368 369 377 private static void putMapEntry(Map map, String name, String value) { 378 String [] newValues = null; 379 String [] oldValues = (String []) map.get(name); 380 if (oldValues == null) { 381 newValues = new String [1]; 382 newValues[0] = value; 383 } else { 384 newValues = new String [oldValues.length + 1]; 385 System.arraycopy(oldValues, 0, newValues, 0, oldValues.length); 386 newValues[oldValues.length] = value; 387 } 388 map.put(name, newValues); 389 } 390 391 396 private static byte convertHexDigit( byte b ) { 397 if ((b >= '0') && (b <= '9')) return (byte)(b - '0'); 398 if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); 399 if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); 400 return 0; 401 } 402 } 403 | Popular Tags |