1 7 8 package java.util.jar; 9 10 import java.io.DataInputStream ; 11 import java.io.DataOutputStream ; 12 import java.io.IOException ; 13 import java.util.HashMap ; 14 import java.util.Map ; 15 import java.util.Set ; 16 import java.util.Collection ; 17 import java.util.AbstractSet ; 18 import java.util.Iterator ; 19 import java.util.logging.Logger ; 20 import java.util.Comparator ; 21 import sun.misc.ASCIICaseInsensitiveComparator; 22 23 37 public class Attributes implements Map <Object ,Object >, Cloneable { 38 41 protected Map <Object ,Object > map; 42 43 46 public Attributes() { 47 this(11); 48 } 49 50 56 public Attributes(int size) { 57 map = new HashMap (size); 58 } 59 60 66 public Attributes(Attributes attr) { 67 map = new HashMap (attr); 68 } 69 70 71 79 public Object get(Object name) { 80 return map.get(name); 81 } 82 83 98 public String getValue(String name) { 99 return (String )get(new Attributes.Name ((String )name)); 100 } 101 102 115 public String getValue(Name name) { 116 return (String )get(name); 117 } 118 119 130 public Object put(Object name, Object value) { 131 return map.put((Attributes.Name )name, (String )value); 132 } 133 134 150 public String putValue(String name, String value) { 151 return (String )put(new Name(name), value); 152 } 153 154 161 public Object remove(Object name) { 162 return map.remove(name); 163 } 164 165 173 public boolean containsValue(Object value) { 174 return map.containsValue(value); 175 } 176 177 183 public boolean containsKey(Object name) { 184 return map.containsKey(name); 185 } 186 187 194 public void putAll(Map <?,?> attr) { 195 if (!Attributes .class.isInstance(attr)) 197 throw new ClassCastException (); 198 for (Map.Entry <?,?> me : (attr).entrySet()) 199 put(me.getKey(), me.getValue()); 200 } 201 202 205 public void clear() { 206 map.clear(); 207 } 208 209 212 public int size() { 213 return map.size(); 214 } 215 216 219 public boolean isEmpty() { 220 return map.isEmpty(); 221 } 222 223 226 public Set <Object > keySet() { 227 return map.keySet(); 228 } 229 230 233 public Collection <Object > values() { 234 return map.values(); 235 } 236 237 241 public Set <Map.Entry <Object ,Object >> entrySet() { 242 return map.entrySet(); 243 } 244 245 253 public boolean equals(Object o) { 254 return map.equals(o); 255 } 256 257 260 public int hashCode() { 261 return map.hashCode(); 262 } 263 264 273 public Object clone() { 274 return new Attributes (this); 275 } 276 277 281 void write(DataOutputStream os) throws IOException { 282 Iterator it = entrySet().iterator(); 283 while (it.hasNext()) { 284 Map.Entry e = (Map.Entry )it.next(); 285 StringBuffer buffer = new StringBuffer ( 286 ((Name)e.getKey()).toString()); 287 buffer.append(": "); 288 289 String value = (String )e.getValue(); 290 if (value != null) { 291 byte[] vb = value.getBytes("UTF8"); 292 value = new String (vb, 0, 0, vb.length); 293 } 294 buffer.append(value); 295 296 buffer.append("\r\n"); 297 Manifest.make72Safe(buffer); 298 os.writeBytes(buffer.toString()); 299 } 300 os.writeBytes("\r\n"); 301 } 302 303 310 void writeMain(DataOutputStream out) throws IOException 311 { 312 String vername = Name.MANIFEST_VERSION.toString(); 314 String version = getValue(vername); 315 if (version == null) { 316 vername = Name.SIGNATURE_VERSION.toString(); 317 version = getValue(vername); 318 } 319 320 if (version != null) { 321 out.writeBytes(vername+": "+version+"\r\n"); 322 } 323 324 Iterator it = entrySet().iterator(); 327 while (it.hasNext()) { 328 Map.Entry e = (Map.Entry )it.next(); 329 String name = ((Name)e.getKey()).toString(); 330 if ((version != null) && ! (name.equalsIgnoreCase(vername))) { 331 332 StringBuffer buffer = new StringBuffer (name); 333 buffer.append(": "); 334 335 String value = (String )e.getValue(); 336 if (value != null) { 337 byte[] vb = value.getBytes("UTF8"); 338 value = new String (vb, 0, 0, vb.length); 339 } 340 buffer.append(value); 341 342 buffer.append("\r\n"); 343 Manifest.make72Safe(buffer); 344 out.writeBytes(buffer.toString()); 345 } 346 } 347 out.writeBytes("\r\n"); 348 } 349 350 354 void read(Manifest.FastInputStream is, byte[] lbuf) throws IOException { 355 String name = null, value = null; 356 byte[] lastline = null; 357 358 int len; 359 while ((len = is.readLine(lbuf)) != -1) { 360 boolean lineContinued = false; 361 if (lbuf[--len] != '\n') { 362 throw new IOException ("line too long"); 363 } 364 if (len > 0 && lbuf[len-1] == '\r') { 365 --len; 366 } 367 if (len == 0) { 368 break; 369 } 370 int i = 0; 371 if (lbuf[0] == ' ') { 372 if (name == null) { 374 throw new IOException ("misplaced continuation line"); 375 } 376 lineContinued = true; 377 byte[] buf = new byte[lastline.length + len - 1]; 378 System.arraycopy(lastline, 0, buf, 0, lastline.length); 379 System.arraycopy(lbuf, 1, buf, lastline.length, len - 1); 380 if (is.peek() == ' ') { 381 lastline = buf; 382 continue; 383 } 384 value = new String (buf, 0, buf.length, "UTF8"); 385 lastline = null; 386 } else { 387 while (lbuf[i++] != ':') { 388 if (i >= len) { 389 throw new IOException ("invalid header field"); 390 } 391 } 392 if (lbuf[i++] != ' ') { 393 throw new IOException ("invalid header field"); 394 } 395 name = new String (lbuf, 0, 0, i - 2); 396 if (is.peek() == ' ') { 397 lastline = new byte[len - i]; 398 System.arraycopy(lbuf, i, lastline, 0, len - i); 399 continue; 400 } 401 value = new String (lbuf, i, len - i, "UTF8"); 402 } 403 try { 404 if ((putValue(name, value) != null) && (!lineContinued)) { 405 Logger.getLogger("java.util.jar").warning( 406 "Duplicate name in Manifest: " + name); 407 } 408 } catch (IllegalArgumentException e) { 409 throw new IOException ("invalid header field name: " + name); 410 } 411 } 412 } 413 414 423 public static class Name { 424 private String name; 425 private int hashCode = -1; 426 427 435 public Name(String name) { 436 if (name == null) { 437 throw new NullPointerException ("name"); 438 } 439 if (!isValid(name)) { 440 throw new IllegalArgumentException (name); 441 } 442 this.name = name.intern(); 443 } 444 445 private static boolean isValid(String name) { 446 int len = name.length(); 447 if (len > 70 || len == 0) { 448 return false; 449 } 450 for (int i = 0; i < len; i++) { 451 if (!isValid(name.charAt(i))) { 452 return false; 453 } 454 } 455 return true; 456 } 457 458 private static boolean isValid(char c) { 459 return isAlpha(c) || isDigit(c) || c == '_' || c == '-'; 460 } 461 462 private static boolean isAlpha(char c) { 463 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 464 } 465 466 private static boolean isDigit(char c) { 467 return c >= '0' && c <= '9'; 468 } 469 470 476 public boolean equals(Object o) { 477 if (o instanceof Name) { 478 Comparator c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER; 479 return c.compare(name, ((Name)o).name) == 0; 480 } else { 481 return false; 482 } 483 } 484 485 488 public int hashCode() { 489 if (hashCode == -1) { 490 hashCode = ASCIICaseInsensitiveComparator.lowerCaseHashCode(name); 491 } 492 return hashCode; 493 } 494 495 498 public String toString() { 499 return name; 500 } 501 502 509 public static final Name MANIFEST_VERSION = new Name("Manifest-Version"); 510 511 517 public static final Name SIGNATURE_VERSION = new Name("Signature-Version"); 518 519 523 public static final Name CONTENT_TYPE = new Name("Content-Type"); 524 525 532 public static final Name CLASS_PATH = new Name("Class-Path"); 533 534 541 public static final Name MAIN_CLASS = new Name("Main-Class"); 542 543 549 public static final Name SEALED = new Name("Sealed"); 550 551 557 public static final Name EXTENSION_LIST = new Name("Extension-List"); 558 559 565 public static final Name EXTENSION_NAME = new Name("Extension-Name"); 566 567 573 public static final Name EXTENSION_INSTALLATION = new Name("Extension-Installation"); 574 575 581 public static final Name IMPLEMENTATION_TITLE = new Name("Implementation-Title"); 582 583 589 public static final Name IMPLEMENTATION_VERSION = new Name("Implementation-Version"); 590 591 597 public static final Name IMPLEMENTATION_VENDOR = new Name("Implementation-Vendor"); 598 599 605 public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id"); 606 607 613 public static final Name IMPLEMENTATION_URL = new Name("Implementation-URL"); 614 615 621 public static final Name SPECIFICATION_TITLE = new Name("Specification-Title"); 622 623 629 public static final Name SPECIFICATION_VERSION = new Name("Specification-Version"); 630 631 637 public static final Name SPECIFICATION_VENDOR = new Name("Specification-Vendor"); 638 } 639 } 640 | Popular Tags |