1 52 53 package com.go.trove.net; 54 55 import java.util.*; 56 import java.text.*; 57 import java.io.*; 58 import com.go.trove.io.*; 59 60 66 public class HttpHeaderMap implements Map, Serializable { 67 private final static TimeZone GMT_ZONE; 68 private final static DateFormat DATE_PARSER_1; 69 private final static DateFormat DATE_PARSER_2; 70 private final static String [] DAYS; 71 private final static String [] MONTHS; 72 73 static { 74 GMT_ZONE = TimeZone.getTimeZone("GMT"); 75 76 DATE_PARSER_1 = 77 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.US); 78 DATE_PARSER_1.setTimeZone(GMT_ZONE); 79 DATE_PARSER_1.setLenient(true); 80 81 DATE_PARSER_2 = 82 new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss", Locale.US); 83 DATE_PARSER_2.setTimeZone(GMT_ZONE); 84 DATE_PARSER_2.setLenient(true); 85 86 DateFormatSymbols symbols = new DateFormatSymbols(Locale.US); 87 DAYS = symbols.getShortWeekdays(); 88 MONTHS = symbols.getShortMonths(); 89 } 90 91 private static void appendDate(CharToByteBuffer buffer, Date d) 92 throws IOException 93 { 94 Calendar c = new GregorianCalendar(GMT_ZONE, Locale.US); 95 c.setTime(d); 96 97 buffer.append(DAYS[c.get(Calendar.DAY_OF_WEEK)]); 98 buffer.append(", "); 99 append2Digit(buffer, c.get(Calendar.DAY_OF_MONTH)); 100 buffer.append(' '); 101 buffer.append(MONTHS[c.get(Calendar.MONTH)]); 102 buffer.append(' '); 103 append4Digit(buffer, c.get(Calendar.YEAR)); 104 buffer.append(' '); 105 append2Digit(buffer, c.get(Calendar.HOUR_OF_DAY)); 106 buffer.append(':'); 107 append2Digit(buffer, c.get(Calendar.MINUTE)); 108 buffer.append(':'); 109 append2Digit(buffer, c.get(Calendar.SECOND)); 110 buffer.append(" GMT"); 111 } 112 113 private static void append2Digit(CharToByteBuffer buffer, int val) 114 throws IOException 115 { 116 buffer.append((char)(val / 10 + '0')); 117 buffer.append((char)(val % 10 + '0')); 118 } 119 120 private static void append4Digit(CharToByteBuffer buffer, int val) 121 throws IOException 122 { 123 if (val < 1000 || val > 9999) { 124 buffer.append(Integer.toString(val)); 125 } 126 else { 127 buffer.append((char)(val / 1000 + '0')); 128 buffer.append((char)(val / 100 % 10 + '0')); 129 buffer.append((char)(val / 10 % 10 + '0')); 130 buffer.append((char)(val % 10 + '0')); 131 } 132 } 133 134 private Map mMap; 135 136 public HttpHeaderMap() { 137 mMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); 138 } 139 140 147 public void readFrom(InputStream in) throws IOException { 148 readFrom(in, new byte[80]); 149 } 150 151 159 public void readFrom(InputStream in, byte[] buffer) throws IOException { 160 String header; 161 while ((header = HttpUtils.readLine(in, buffer, 4000)) != null) { 162 if (header.length() == 0) { 163 break; 164 } 165 processHeaderLine(header); 166 } 167 } 168 169 177 public void readFrom(InputStream in, char[] buffer) throws IOException { 178 String header; 179 while ((header = HttpUtils.readLine(in, buffer, 4000)) != null) { 180 if (header.length() == 0) { 181 break; 182 } 183 processHeaderLine(header); 184 } 185 } 186 187 private void processHeaderLine(String header) { 188 int index = header.indexOf(':'); 189 if (index < 0) { 190 return; 191 } 192 193 String name = header.substring(0, index); 194 195 String value; 196 int length = header.length(); 197 parseValue: { 198 do { 199 if (++index >= length) { 200 value = ""; 201 break parseValue; 202 } 203 } while (header.charAt(index) == ' '); 204 205 value = header.substring(index); 206 } 207 208 if ("Cookie".equalsIgnoreCase(name) || 209 "Set-Cookie".equalsIgnoreCase(name) || 210 (value.indexOf(',') == 3 && 211 (value.startsWith("Mon") || 212 value.startsWith("Tue") || 213 value.startsWith("Wed") || 214 value.startsWith("Thu") || 215 value.startsWith("Fri") || 216 value.startsWith("Sat") || 217 value.startsWith("Sun")))) { 218 219 add(name, value.trim()); 220 } 221 else { 222 while ((index = value.indexOf(',')) >= 0) { 225 add(name, value.substring(0, index).trim()); 226 value = value.substring(index + 1); 227 } 228 229 add(name, value.trim()); 230 } 231 } 232 233 public void writeTo(OutputStream out) throws IOException { 234 CharToByteBuffer buffer = new FastCharToByteBuffer 235 (new DefaultByteBuffer(), "8859_1"); 236 buffer = new InternedCharToByteBuffer(buffer); 237 appendTo(buffer); 238 buffer.writeTo(out); 239 } 240 241 public void appendTo(CharToByteBuffer buffer) throws IOException { 242 Iterator it = mMap.entrySet().iterator(); 243 while (it.hasNext()) { 244 Map.Entry entry = (Map.Entry)it.next(); 245 Object key = entry.getKey(); 246 Object value = entry.getValue(); 247 248 if (key == null || value == null) { 249 continue; 250 } 251 252 String strKey = key.toString(); 253 254 if (value instanceof List) { 255 Iterator values = ((List)value).iterator(); 256 if ("Set-Cookie".equalsIgnoreCase(strKey)) { 257 while (values.hasNext()) { 258 buffer.append(strKey); 259 buffer.append(": "); 260 value = values.next(); 261 if (value instanceof Date) { 262 appendDate(buffer, (Date)value); 263 } 264 else { 265 buffer.append(value.toString()); 266 } 267 buffer.append("\r\n"); 268 } 269 } 270 else { 271 int count = 0; 273 while (values.hasNext()) { 274 value = values.next(); 275 276 if (count < 0) { 277 buffer.append("\r\n"); 278 count = 0; 279 } 280 if (count++ == 0) { 281 buffer.append(strKey); 282 buffer.append(": "); 283 } 284 285 if (value instanceof Date) { 286 if (count > 1) { 288 buffer.append("\r\n"); 289 buffer.append(strKey); 290 buffer.append(": "); 291 } 292 appendDate(buffer, (Date)value); 293 count = -1; 294 } 295 else { 296 String strVal = value.toString(); 297 if (strVal.indexOf(',') < 0) { 298 if (count > 1) { 299 buffer.append(','); 300 } 301 buffer.append(strVal); 302 } 303 else { 304 if (count > 1) { 306 buffer.append("\r\n"); 307 buffer.append(strKey); 308 buffer.append(": "); 309 } 310 buffer.append(strVal); 311 count = -1; 312 } 313 } 314 } 315 buffer.append("\r\n"); 316 } 317 } 318 else { 319 buffer.append(strKey); 320 buffer.append(": "); 321 if (value instanceof Date) { 322 appendDate(buffer, (Date)value); 323 } 324 else { 325 buffer.append(value.toString()); 326 } 327 buffer.append("\r\n"); 328 } 329 } 330 } 331 332 public int size() { 333 return mMap.size(); 334 } 335 336 public boolean isEmpty() { 337 return mMap.isEmpty(); 338 } 339 340 public boolean containsKey(Object key) { 341 return mMap.containsKey(key); 342 } 343 344 public boolean containsValue(Object value) { 345 Iterator it = mMap.values().iterator(); 346 while (it.hasNext()) { 347 Object obj = it.next(); 348 if (obj instanceof List) { 349 Iterator it2 = ((List)obj).iterator(); 350 while (it2.hasNext()) { 351 obj = it2.next(); 352 return (value == null) ? obj == null : value.equals(obj); 353 } 354 } 355 else { 356 return (value == null) ? obj == null : value.equals(obj); 357 } 358 } 359 return false; 360 } 361 362 365 public Object get(Object key) { 366 Object value = mMap.get(key); 367 if (value instanceof List) { 368 return ((List)value).get(0); 369 } 370 else { 371 return value; 372 } 373 } 374 375 public String getString(Object key) { 376 Object obj = get(key); 377 if (obj instanceof String ) { 378 return (String )obj; 379 } 380 else if (obj != null) { 381 return obj.toString(); 382 } 383 return null; 384 } 385 386 public Integer getInteger(Object key) { 387 Object obj = get(key); 388 if (obj instanceof Integer ) { 389 return (Integer )obj; 390 } 391 else if (obj != null) { 392 try { 393 return new Integer (obj.toString()); 394 } 395 catch (NumberFormatException e) { 396 } 397 } 398 return null; 399 } 400 401 public Date getDate(Object key) { 402 Object obj = get(key); 403 if (obj instanceof Date) { 404 return (Date)obj; 405 } 406 else if (obj == null) { 407 return null; 408 } 409 410 String val = obj.toString(); 411 412 int index = val.indexOf(';'); 415 if (index >= 0) { 416 val = val.substring(0, index); 417 } 418 419 Date date; 420 421 try { 422 synchronized (DATE_PARSER_1) { 423 date = DATE_PARSER_1.parse(val); 424 } 425 } 426 catch (ParseException e) { 427 try { 428 synchronized (DATE_PARSER_2) { 429 date = DATE_PARSER_2.parse(val); 430 } 431 } 432 catch (ParseException e2) { 433 return null; 434 } 435 } 436 437 return date; 438 } 439 440 441 445 public List getAll(Object key) { 446 Object value = mMap.get(key); 447 if (value instanceof List) { 448 return ((List)value); 449 } 450 else { 451 List list = new ArrayList(); 452 if (value != null || mMap.containsKey(key)) { 453 list.add(value); 454 } 455 mMap.put(key, list); 456 return list; 457 } 458 } 459 460 463 public Object put(Object key, Object value) { 464 if (value instanceof List) { 465 return mMap.put(key, new ArrayList((List)value)); 466 } 467 else { 468 return mMap.put(key, value); 469 } 470 } 471 472 475 public void add(Object key, Object value) { 476 Object existing = mMap.get(key); 477 if (existing instanceof List) { 478 if (value instanceof List) { 479 ((List)existing).addAll((List)value); 480 } 481 else { 482 ((List)existing).add(value); 483 } 484 } 485 else if (existing == null && !mMap.containsKey(key)) { 486 if (value instanceof List) { 487 mMap.put(key, new ArrayList((List)value)); 488 } 489 else { 490 mMap.put(key, value); 491 } 492 } 493 else { 494 List list = new ArrayList(); 495 list.add(existing); 496 if (value instanceof List) { 497 list.addAll((List)value); 498 } 499 else { 500 list.add(value); 501 } 502 mMap.put(key, list); 503 } 504 } 505 506 public Object remove(Object key) { 507 return mMap.remove(key); 508 } 509 510 public void putAll(Map map) { 511 mMap.putAll(map); 512 } 513 514 public void clear() { 515 mMap.clear(); 516 } 517 518 public Set keySet() { 519 return mMap.keySet(); 520 } 521 522 public Collection values() { 523 return mMap.values(); 524 } 525 526 public Set entrySet() { 527 return mMap.entrySet(); 528 } 529 530 public boolean equals(Object obj) { 531 return mMap.equals(obj); 532 } 533 534 public int hashCode() { 535 return mMap.hashCode(); 536 } 537 538 public String toString() { 539 return super.toString() + ":" + mMap.toString(); 540 } 541 } 542 | Popular Tags |