1 19 package org.openide.filesystems; 20 21 import org.openide.util.SharedClassObject; 22 import org.openide.util.Utilities; 23 import org.openide.util.io.NbMarshalledObject; 24 import org.openide.util.io.NbObjectInputStream; 25 26 import java.io.*; 27 28 import java.lang.reflect.*; 29 30 import java.net.URL ; 31 32 import java.util.*; 33 import org.openide.util.Exceptions; 34 35 36 97 @SuppressWarnings ("unchecked") 98 final class XMLMapAttr implements Map { 99 Map map; 100 101 102 public XMLMapAttr() { 103 this.map = new HashMap(5); 104 } 105 106 static Attr createAttributeAndDecode(String key, String value) { 107 if (Attr.isValid(key) == Attr.isValid("stringvalue")) { value = Attr.decode(value); 109 } 110 111 return new Attr(key, value); 112 } 113 114 static Attr createAttribute(int index, String value) { 115 return new Attr(index, value); 116 } 117 118 122 public Object get(final Object p1) { 123 Object obj; 124 125 try { 126 obj = getAttribute(p1); 127 } catch (Exception e) { 128 obj = null; 129 ExternalUtil.exception(e); 130 } 131 132 return obj; 133 } 134 135 139 public Object get(final Object p1, Object [] params) { 140 Object obj; 141 142 try { 143 obj = getAttribute(p1, params); 144 } catch (Exception e) { 145 obj = null; 146 ExternalUtil.exception(e); 147 } 148 149 return obj; 150 } 151 152 154 Object getAttribute(Object attrName) throws Exception { 155 return getAttribute(attrName, null); 156 } 157 158 private Object getAttribute(Object attrName, Object [] params) 159 throws Exception { 160 Attr attr; 161 String origAttrName = (String ) attrName; 162 Object [] keyValuePair = ModifiedAttribute.translateInto((String ) attrName, null); 163 attrName = (String ) keyValuePair[0]; 164 165 synchronized (this) { 166 attr = (Attr) map.get(attrName); 167 } 168 169 Object retVal = null; 170 171 try { 172 retVal = (attr == null) ? attr : attr.get(params); 173 } catch (Exception e) { 174 ExternalUtil.annotate(e, "attrName = " + attrName); throw e; 176 } 177 178 if (retVal instanceof ModifiedAttribute) { 179 Object res = ((ModifiedAttribute) retVal).getValue(origAttrName); 180 181 if (res instanceof Attr) { 182 return ((Attr) res).get(params); 183 } else { 184 return res; 185 } 186 } 187 188 return retVal; 189 } 190 191 197 public synchronized Object put(final Object p1, final Object p2) { 198 return put(p1, p2, true); 199 } 200 201 synchronized Object put(final Object p1, final Object p2, boolean decode) { 202 if ((p1 == null) || !(p1 instanceof String )) { 203 return null; 204 } 205 206 Object [] keyValuePair = ModifiedAttribute.translateInto((String ) p1, p2); 207 String key = (String ) keyValuePair[0]; 208 Object value = keyValuePair[1]; 209 Object toStore = ((value == null) || value instanceof Attr) ? value : new Attr(value); 210 211 if (decode) { 212 key = Attr.decode(key).intern(); 213 } 214 215 return map.put(key, toStore); 216 } 217 218 222 public static void writeHeading(PrintWriter pw) { 223 pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); pw.println( 225 "<!DOCTYPE attributes PUBLIC \"-//NetBeans//DTD DefaultAttributes 1.0//EN\" \"http://www.netbeans.org/dtds/attributes-1_0.dtd\">" 226 ); pw.println("<attributes version=\"1.0\">"); } 229 230 234 public static void writeEnding(PrintWriter pw) { 235 pw.println("</attributes>"); } 237 238 244 public synchronized void write(PrintWriter pw, final String fileName, String blockPrefix) { 245 boolean isHeadingWr = false; 246 247 if (isEmpty()) { 248 return; 249 } 250 251 SortedSet<String > attrNames = new TreeSet<String >(); 253 Iterator entryIter = map.entrySet().iterator(); 254 255 while (entryIter.hasNext()) { 256 Map.Entry entry = (Map.Entry) entryIter.next(); 257 258 String attrName = (String ) entry.getKey(); 259 Attr attr = (Attr) entry.getValue(); 260 261 if ((attrName == null) || (attr == null) || (attrName.length() == 0) || (attr.isValid() == -1)) { 262 if ((attrName != null) && (attrName.length() != 0) && ((attr == null) || (attr.isValid() == -1))) { 263 entryIter.remove(); 264 } 265 266 continue; 267 } 268 269 attrNames.add(attrName); 270 } 271 272 entryIter = attrNames.iterator(); 273 274 while (entryIter.hasNext()) { 275 String attrName = (String ) entryIter.next(); 276 Attr attr = (Attr) map.get(attrName); 277 278 if (attr != null) { 279 attr.transformMe(); 280 } 281 282 if (!isHeadingWr) { 283 isHeadingWr = true; 284 285 String quotedFileName = fileName; 286 287 try { 288 quotedFileName = org.openide.xml.XMLUtil.toAttributeValue(fileName); 289 } catch (IOException ignore) { 290 } 291 292 pw.println(blockPrefix + "<fileobject name=\"" + quotedFileName + "\">"); } 294 295 pw.println( 296 blockPrefix + blockPrefix + "<attr name=\"" + attr.getAttrNameForPrint(attrName) + "\" " + 297 attr.getKeyForPrint() + "=\"" + attr.getValueForPrint() + "\"/>" 298 ); attr.maybeAddSerValueComment(pw, blockPrefix + blockPrefix); 300 } 301 302 if (isHeadingWr) { 303 pw.println(blockPrefix + "</fileobject>"); } 305 } 306 307 public synchronized void clear() { 308 map.clear(); 309 } 310 311 public synchronized Object remove(Object p1) { 312 return map.remove(p1); 313 } 314 315 public synchronized boolean containsValue(Object p1) { 316 return map.containsValue(p1); 317 } 318 319 public synchronized int hashCode() { 320 return map.hashCode(); 321 } 322 323 public synchronized java.util.Set <String > keySet() { 324 return map.keySet(); 325 } 326 327 public synchronized java.util.Collection values() { 328 return map.values(); 329 } 330 331 public synchronized java.util.Set entrySet() { 333 return map.entrySet(); 334 } 335 336 public synchronized void putAll(java.util.Map p1) { 337 map.putAll(p1); 338 } 339 340 public synchronized boolean containsKey(Object p1) { 341 return map.containsKey(p1); 342 } 343 344 public synchronized boolean isEmpty() { 345 return map.isEmpty(); 346 } 347 348 public synchronized boolean equals(Object p1) { 349 return map.equals(p1); 350 } 351 352 public synchronized int size() { 353 return map.size(); 354 } 355 356 361 final static class Attr extends java.lang.Object { 362 private static final String [] ALLOWED_ATTR_KEYS = { 364 "bytevalue", "shortvalue", "intvalue", "longvalue", "floatvalue", "doublevalue", "boolvalue", "charvalue", 365 "stringvalue", "methodvalue", "serialvalue", "urlvalue", "newvalue" 366 }; private String value; 368 private int keyIndex; 369 private Object obj; 371 private Attr(Object obj) { 372 this.obj = obj; 373 } 374 375 private Attr(int index, String value) { 376 keyIndex = index; 377 this.value = (value != null) ? value.intern() : null; 378 } 379 380 385 private Attr(String key, String value) { 386 keyIndex = isValid(key); 387 this.value = value.intern(); 388 } 389 390 393 static String [] getAttrTypes() { 394 return ALLOWED_ATTR_KEYS; 395 } 396 397 402 private final void putEntry(String key, String value) { 403 this.keyIndex = isValid(key); 404 this.value = value.intern(); 405 } 406 407 410 static Object unMarshallObjectRecursively(Object mo) { 411 Object o = mo; 412 413 while (o instanceof NbMarshalledObject) { 414 try { 415 o = ((NbMarshalledObject) o).get(); 416 } catch (IOException e) { 417 ExternalUtil.exception(e); 418 419 return mo; 420 } catch (ClassNotFoundException e) { 421 ExternalUtil.exception(e); 422 423 return mo; 424 } 425 } 426 427 return (o == null) ? mo : o; 428 } 429 430 431 private void transformMe() { 432 int objType; 433 434 if (obj == null) { 435 return; 436 } 437 438 Object unObj = unMarshallObjectRecursively(obj); 439 440 if (unObj != null) { 441 if ((objType = XMLMapAttr.Attr.distinguishObject(unObj)) != XMLMapAttr.Attr.isValid("SERIALVALUE")) { obj = null; 443 putEntry(ALLOWED_ATTR_KEYS[objType], unObj.toString()); 444 } else { 445 String newValue; 446 447 try { 448 newValue = encodeValue(unObj); 449 } catch (IOException iox) { 450 return; 451 } 452 453 obj = null; 454 putEntry(ALLOWED_ATTR_KEYS[objType], newValue); 455 } 456 } 457 } 458 459 462 static int distinguishObject(Object o) { 463 if (o instanceof Byte ) { 464 return isValid("BYTEVALUE"); } 466 467 if (o instanceof Short ) { 468 return isValid("SHORTVALUE"); } 470 471 if (o instanceof Integer ) { 472 return isValid("INTVALUE"); } 474 475 if (o instanceof Long ) { 476 return isValid("LONGVALUE"); } 478 479 if (o instanceof Float ) { 480 return isValid("FLOATVALUE"); } 482 483 if (o instanceof Double ) { 484 return isValid("DOUBLEVALUE"); } 486 487 if (o instanceof Boolean ) { 488 return isValid("BOOLVALUE"); } 490 491 if (o instanceof Character ) { 492 return isValid("CHARVALUE"); } 494 495 if (o instanceof String ) { 496 return isValid("STRINGVALUE"); } 498 499 if (o instanceof URL ) { 500 return isValid("URLVALUE"); } 502 503 return isValid("SERIALVALUE"); } 505 506 static String encode(String inStr) { 507 try { 508 inStr = org.openide.xml.XMLUtil.toAttributeValue(inStr); 509 } catch (Exception ignore) { 510 } 511 512 StringBuffer outStr = new StringBuffer (6 * inStr.length()); 513 514 for (int i = 0; i < inStr.length(); i++) { 515 if (Character.isISOControl(inStr.charAt(i)) || isEncodedChar(i, inStr)) { 516 outStr.append(encodeChar(inStr.charAt(i))); 517 518 continue; 519 } 520 521 outStr.append(inStr.charAt(i)); 522 } 523 524 return outStr.toString(); 525 } 526 527 static String encodeChar(char ch) { 528 String encChar = Integer.toString((int) ch, 16); 529 530 return "\\u" + "0000".substring(0, "0000".length() - encChar.length()).concat(encChar); } 532 533 static String decode(final String inStr) { 534 StringBuffer outStr = new StringBuffer (inStr.length()); 535 536 try { 537 for (int i = 0; i < inStr.length(); i++) { 538 if (isEncodedChar(i, inStr)) { 539 String decChar = inStr.substring(i + 2, i + 6); 540 outStr.append((char) Integer.parseInt(decChar, 16)); 541 i += 5; 542 } else { 543 outStr.append(inStr.charAt(i)); 544 } 545 } 546 } catch (NumberFormatException e) { 547 Exceptions.printStackTrace(e); 548 549 return inStr; 550 } 551 552 return outStr.toString(); 553 } 554 555 private static boolean isEncodedChar(final int currentPosition, final String inStr) { 556 boolean isEncodedChar = (currentPosition + 5) < inStr.length(); 557 558 if (isEncodedChar) { 559 isEncodedChar &= ((inStr.charAt(currentPosition) == '\\') && 560 (inStr.charAt(currentPosition + 1) == 'u')); 561 562 for (int i = currentPosition + 2; isEncodedChar && (i < (currentPosition + 6)); i++) { 563 char c = inStr.charAt(i); 564 isEncodedChar &= (Character.digit(c, 16) != -1); 565 } 566 } 567 568 return isEncodedChar; 569 } 570 571 575 private Object get() throws Exception { 576 return getObject(null); } 578 579 584 private Object get(Object [] objs) throws Exception { 585 return getObject(objs); 586 } 587 588 591 final String getKey() { 592 String [] keyArray = getAttrTypes(); 593 594 if (obj != null) { 595 return "serialvalue"; } 597 598 if (isValid() == -1) { 599 return ""; } 601 602 return keyArray[keyIndex]; 603 } 604 605 608 final String getValue() { 609 if (obj != null) { 610 getValue(obj); 611 } 612 613 return (value != null) ? value : ""; } 615 616 static final String getValue(Object obj) { 617 try { 618 return encodeValue(obj); } catch (IOException ioe) { 620 return ""; } 622 } 623 624 final String getValueForPrint() { 625 if (obj != null) { 626 Attr modifAttr = null; 627 628 if (obj instanceof ModifiedAttribute) { 629 modifAttr = (Attr) ((ModifiedAttribute) obj).getValue(); 630 } 631 632 return (modifAttr != null) ? encode(modifAttr.getValue()) : encode(getValue()); 633 } 634 635 return (value != null) ? encode(value) : ""; } 637 638 final String getKeyForPrint() { 639 if ((obj != null) && obj instanceof ModifiedAttribute) { 640 Attr modifAttr = (Attr) ((ModifiedAttribute) obj).getValue(); 641 int keyIdx = Attr.isValid("SERIALVALUE"); 643 if (modifAttr != null) { 644 keyIdx = distinguishObject(modifAttr.getValue()); 645 } 646 647 String [] keyArray = getAttrTypes(); 648 649 return keyArray[keyIdx]; 650 } 651 652 return getKey(); 653 } 654 655 final String getAttrNameForPrint(String attrName) { 656 if ((obj != null) && obj instanceof ModifiedAttribute) { 657 Object [] retVal = ModifiedAttribute.revert(attrName, obj); 658 659 return encode((String ) retVal[0]); 660 } 661 662 return encode(attrName); 663 } 664 665 final void maybeAddSerValueComment(PrintWriter pw, String indent) { 666 if (obj != null) { 667 Object modifObj = null; 668 669 if (obj instanceof ModifiedAttribute) { 670 modifObj = ((Attr) ((ModifiedAttribute) obj).getValue()).getValue(); 671 672 if (distinguishObject(modifObj) != Attr.isValid("SERIALVALUE")) { 674 return; 675 } 676 } 677 678 pw.print(indent); 684 pw.print("<!-- "); 686 String s = (modifObj != null) ? modifObj.toString() : obj.toString(); 687 688 if (s.indexOf("--") != -1) { 690 s = s.replace('-', '_'); } 693 694 pw.print(s); 695 pw.println(" -->"); } 697 } 698 699 705 static Object decodeValue(String value) throws IOException { 706 if ((value == null) || (value.length() == 0)) { 707 return null; 708 } 709 710 byte[] bytes = new byte[value.length() / 2]; 711 int tempI; 712 int count = 0; 713 714 for (int i = 0; i < value.length(); i += 2) { 715 try { 716 tempI = Integer.parseInt(value.substring(i, i + 2), 16); 717 718 if (tempI > 127) { 719 tempI -= 256; 720 } 721 722 bytes[count++] = (byte) tempI; 723 } catch (NumberFormatException e) { 724 throw (IOException) ExternalUtil.copyAnnotation(new IOException(), e); 725 } 726 } 727 728 ByteArrayInputStream bis = new ByteArrayInputStream(bytes, 0, count); 729 730 try { 731 ObjectInputStream ois = new NbObjectInputStream(bis); 732 Object ret = ois.readObject(); 733 734 return ret; 735 } catch (Exception e) { 736 throw (IOException) ExternalUtil.copyAnnotation(new IOException(), e); 737 } 738 739 740 741 } 743 744 750 static String encodeValue(Object value) throws IOException { 751 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 752 753 try { 754 ObjectOutputStream oos = new ObjectOutputStream(bos); 755 oos.writeObject(value); 756 oos.close(); 757 } catch (Exception e) { 758 throw (IOException) ExternalUtil.copyAnnotation(new IOException(), e); 759 } 760 761 byte[] bArray = bos.toByteArray(); 762 StringBuffer strBuff = new StringBuffer (bArray.length * 2); 763 764 for (int i = 0; i < bArray.length; i++) { 765 if ((bArray[i] < 16) && (bArray[i] >= 0)) { 766 strBuff.append("0"); } 768 769 strBuff.append(Integer.toHexString((bArray[i] < 0) ? (bArray[i] + 256) : bArray[i])); 770 } 771 772 return strBuff.toString(); 773 } 774 775 781 private Object getObject(Object [] params) throws Exception { 782 int index; 783 784 if (obj != null) { 785 return obj; } 787 788 if ((index = isValid()) != -1) { 789 try { 790 switch (index) { 791 case 0: 792 return new Byte (value); 793 794 case 1: 795 return new Short (value); 796 797 case 2: 798 return new Integer (value); 800 case 3: 801 return new Long (value); 802 803 case 4: 804 return new Float (value); 805 806 case 5: 807 return new Double (value); 808 809 case 6: 810 return Boolean.valueOf(value); 811 812 case 7: 813 814 if (value.trim().length() != 1) { 815 break; 816 } 817 818 return new Character (value.charAt(0)); 819 820 case 8: 821 return value; 822 823 case 9: 824 return methodValue(value, params); 825 826 case 10: 827 return decodeValue(value); 828 829 case 11: 830 return new URL (value); 831 832 case 12: 833 834 Class cls = ExternalUtil.findClass(Utilities.translate(value)); 836 837 if (SharedClassObject.class.isAssignableFrom(cls)) { 838 return SharedClassObject.findObject(cls, true); 839 } else { 840 return cls.newInstance(); 841 } 842 } 843 } catch (Exception exc) { 844 ExternalUtil.annotate(exc, "value = " + value); throw exc; 846 } catch (LinkageError e) { 847 throw (ClassNotFoundException ) ExternalUtil.annotate(new ClassNotFoundException (value), e); 848 } 849 } 850 851 throw new InstantiationException (value); 852 } 853 854 858 private final Object methodValue(String value, Object [] params) 859 throws Exception { 860 int sepIdx = value.lastIndexOf('.'); 861 862 if (sepIdx != -1) { 863 String methodName = value.substring(sepIdx + 1); 864 Class cls = ExternalUtil.findClass(value.substring(0, sepIdx)); 865 FileObject fo = null; 866 String attrName = null; 867 868 for (int i = 0; i < params.length; i++) { 869 if ((fo == null) && params[i] instanceof FileObject) { 870 fo = (FileObject) params[i]; 871 } 872 873 if ((attrName == null) && params[i] instanceof String ) { 874 attrName = (String ) params[i]; 875 } 876 } 877 878 Object [] paramArray = new Object [] { 879 new Class [] { FileObject.class, String .class }, new Class [] { String .class, FileObject.class }, 880 new Class [] { FileObject.class }, new Class [] { String .class }, new Class [] { }, 881 new Class [] { Map.class, String .class }, new Class [] { Map.class }, 882 }; 883 884 boolean both = ((fo != null) && (attrName != null)); 885 Object [] objectsList = new Object [7]; 886 objectsList[0] = (both) ? new Object [] { fo, attrName } : null; 887 objectsList[1] = (both) ? new Object [] { attrName, fo } : null; 888 objectsList[2] = (fo != null) ? new Object [] { fo } : null; 889 objectsList[3] = (attrName != null) ? new Object [] { attrName } : null; 890 objectsList[4] = new Object [] { }; 891 892 Map fileMap = wrapToMap(fo); 893 objectsList[5] = attrName != null ? new Object [] { fileMap, attrName } : null; 894 objectsList[6] = new Object [] { fileMap }; 895 896 for (int i = 0; i < paramArray.length; i++) { 897 Object [] objArray = (Object []) objectsList[i]; 898 899 if (objArray == null) { 900 continue; 901 } 902 903 try { 904 Method method = cls.getDeclaredMethod(methodName, (Class []) paramArray[i]); 905 906 if (method != null) { 907 method.setAccessible(true); 908 909 return method.invoke(null, objArray); 910 } 911 } catch (NoSuchMethodException nsmExc) { 912 continue; 913 } 914 } 915 } 916 917 throw new InstantiationException (value); 918 } 919 920 static final Map wrapToMap(FileObject fo) { 921 return fo == null ? Collections.EMPTY_MAP : new FileMap(fo); 922 } 923 924 928 final int isValid() { 929 String [] keyArray = getAttrTypes(); 930 931 if (obj != null) { 932 return isValid("SERIALVALUE"); } 934 935 if ((keyIndex >= keyArray.length) || (keyIndex < 0)) { 936 return -1; 937 } 938 939 return keyIndex; 940 } 941 942 946 final static int isValid(String key) { 947 int index = -1; 948 int i; 949 String [] strArray = getAttrTypes(); 950 String trimmedKey = key.trim(); 951 952 for (i = 0; i < strArray.length; i++) { 953 if (trimmedKey.equalsIgnoreCase(strArray[i]) == true) { 954 index = i; 955 956 break; 957 } 958 } 959 960 return index; 961 } 962 963 public boolean equals(Object obj) { 964 if (obj instanceof Attr) { 965 Attr other = (Attr)obj; 966 967 if (other.keyIndex != keyIndex) { 968 return false; 969 } 970 971 return other.value.equals(value); 972 } 973 return false; 974 } 975 976 public int hashCode() { 977 return 743 + keyIndex << 8 + value.hashCode(); 978 } 979 } 980 981 989 static class ModifiedAttribute implements java.io.Serializable { 990 991 static final long serialVersionUID = 84214031923497718L; 992 private final static String [] fragments = new String [] { "transient:" }; private int modifier = 0; 994 private Object origAttrValue = null; 995 996 997 private ModifiedAttribute(Object origAttrValue) { 998 this.origAttrValue = origAttrValue; 999 } 1000 1001 1012 static Object [] translateInto(String attrName, Object value) { 1013 String newAttrName = attrName; 1014 Object newValue = value; 1015 ModifiedAttribute attr = null; 1016 1017 for (int i = 0; i < fragments.length; i++) { 1018 String fragment = fragments[i]; 1019 int idx = newAttrName.indexOf(fragment); 1020 1021 if (idx != -1) { 1022 1023 newAttrName = newAttrName.substring(0, idx) + newAttrName.substring(idx + fragment.length()); 1024 1025 if (attr == null) { 1026 newValue = attr = new ModifiedAttribute(value); 1027 } 1028 1029 attr.modifier |= (1 << i); } 1031 } 1032 1033 return new Object [] { newAttrName, newValue }; 1034 } 1035 1036 1039 static Object [] revert(String attrName, Object value) { 1040 if (!(value instanceof ModifiedAttribute) || (value == null)) { 1041 return new Object [] { attrName, value }; 1042 } 1043 1044 ModifiedAttribute attr = (ModifiedAttribute) value; 1045 String newAttrName = attrName; 1046 Object newValue = attr; 1047 1048 for (int i = 0; i < fragments.length; i++) { 1049 String fragment = fragments[i]; 1050 1051 if (((attr.modifier & (1 << i)) != 0) && (fragment != null)) { 1052 1053 newAttrName = fragment + newAttrName; 1054 1055 if (newValue instanceof ModifiedAttribute) { 1056 newValue = attr.origAttrValue; 1057 } 1058 } 1059 } 1060 1061 return new Object [] { newAttrName, newValue }; 1062 } 1063 1064 1069 Object getValue(String attrName) { 1070 for (int i = 0; i < fragments.length; i++) { 1071 String fragment = fragments[i]; 1072 int idx = attrName.indexOf(fragment); 1073 1074 if (idx != -1) { 1075 return this; 1076 } 1077 } 1078 1079 return origAttrValue; 1080 } 1081 1082 1085 Object getValue() { 1086 return getValue(""); } 1088 1089 1095 static boolean isTransient(FileObject fo, String attrName) { 1096 Object value = fo.getAttribute(fragments[0] + attrName); 1097 1098 if (value instanceof ModifiedAttribute) { 1099 return ((((ModifiedAttribute) value).modifier & (1 << 0)) == 0) ? false : true; 1100 } 1101 1102 return false; 1103 } 1104 } 1105 1106 private static final class FileMap extends AbstractMap<String ,Object > { 1107 private FileObject fo; 1108 1109 private FileMap (FileObject fo) { 1110 this.fo = fo; 1111} 1112 1113 public Set<Map.Entry<String ,Object >> entrySet() { 1114 return new AttrFileSet(fo); 1115 } 1116 1117 public Object get(String key) { 1118 return fo.getAttribute(key); 1119 } 1120 1121 public Object remove(Object key) { 1122 throw new UnsupportedOperationException (); 1123 } 1124 1125 public Object put(String key, Object value) { 1126 throw new UnsupportedOperationException (); 1127 } 1128 1129 } 1130 private static final class AttrFileSet extends AbstractSet<Map.Entry<String ,Object >> { 1131 private FileObject fo; 1132 1133 private AttrFileSet(FileObject fo) { 1134 this.fo = fo; 1135 } 1136 1137 public Iterator<Map.Entry<String , Object >> iterator() { 1138 class Iter implements Iterator<Map.Entry<String , Object >> { 1139 Enumeration<String > attrs = fo.getAttributes(); 1140 1141 public boolean hasNext() { 1142 return attrs.hasMoreElements(); 1143 } 1144 1145 public Map.Entry<String , Object > next() { 1146 String s = attrs.nextElement(); 1147 return new FOEntry(fo, s); 1148 } 1149 1150 public void remove() { 1151 throw new UnsupportedOperationException (); 1152 } 1153 } 1154 return new Iter(); 1155 } 1156 1157 public int size() { 1158 Enumeration<String > all = fo.getAttributes(); 1159 int cnt = 0; 1160 while (all.hasMoreElements()) { 1161 cnt++; 1162 all.nextElement(); 1163 } 1164 return cnt; 1165 } 1166 1167 public boolean remove(Object o) { 1168 throw new UnsupportedOperationException (); 1169 } 1170 } 1172 private static final class FOEntry implements Map.Entry<String , Object > { 1173 private FileObject fo; 1174 private String attr; 1175 1176 private FOEntry(FileObject fo, String attr) { 1177 this.fo = fo; 1178 this.attr = attr; 1179 } 1180 1181 public String getKey() { 1182 return attr; 1183 } 1184 1185 public Object getValue() { 1186 return fo.getAttribute(attr); 1187 } 1188 1189 public Object setValue(Object value) { 1190 throw new UnsupportedOperationException (); 1191 } 1192 } } 1194 | Popular Tags |