1 16 17 package org.apache.xerces.util; 18 19 import org.apache.xerces.xni.Augmentations; 20 import org.apache.xerces.xni.QName; 21 import org.apache.xerces.xni.XMLAttributes; 22 23 42 public class XMLAttributesImpl 43 implements XMLAttributes { 44 45 49 50 protected static final int TABLE_SIZE = 101; 51 52 56 protected static final int SIZE_LIMIT = 20; 57 58 62 64 65 protected boolean fNamespaces = true; 66 67 69 74 protected int fLargeCount = 1; 75 76 77 protected int fLength; 78 79 80 protected Attribute[] fAttributes = new Attribute[4]; 81 82 86 protected Attribute[] fAttributeTableView; 87 88 94 protected int[] fAttributeTableViewChainState; 95 96 99 protected int fTableViewBuckets; 100 101 104 protected boolean fIsTableViewConsistent; 105 106 110 111 public XMLAttributesImpl() { 112 this(TABLE_SIZE); 113 } 114 115 118 public XMLAttributesImpl(int tableSize) { 119 fTableViewBuckets = tableSize; 120 for (int i = 0; i < fAttributes.length; i++) { 121 fAttributes[i] = new Attribute(); 122 } 123 } 125 129 137 public void setNamespaces(boolean namespaces) { 138 fNamespaces = namespaces; 139 } 141 145 173 public int addAttribute(QName name, String type, String value) { 174 175 int index; 176 if (fLength < SIZE_LIMIT) { 177 index = name.uri != null && !name.uri.equals("") 178 ? getIndexFast(name.uri, name.localpart) 179 : getIndexFast(name.rawname); 180 181 if (index == -1) { 182 index = fLength; 183 if (fLength++ == fAttributes.length) { 184 Attribute[] attributes = new Attribute[fAttributes.length + 4]; 185 System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length); 186 for (int i = fAttributes.length; i < attributes.length; i++) { 187 attributes[i] = new Attribute(); 188 } 189 fAttributes = attributes; 190 } 191 } 192 } 193 else if (name.uri == null || 194 name.uri.length() == 0 || 195 (index = getIndexFast(name.uri, name.localpart)) == -1) { 196 197 205 if (!fIsTableViewConsistent || fLength == SIZE_LIMIT) { 206 prepareAndPopulateTableView(); 207 fIsTableViewConsistent = true; 208 } 209 210 int bucket = getTableViewBucket(name.rawname); 211 212 if (fAttributeTableViewChainState[bucket] != fLargeCount) { 215 index = fLength; 216 if (fLength++ == fAttributes.length) { 217 Attribute[] attributes = new Attribute[fAttributes.length << 1]; 218 System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length); 219 for (int i = fAttributes.length; i < attributes.length; i++) { 220 attributes[i] = new Attribute(); 221 } 222 fAttributes = attributes; 223 } 224 225 fAttributeTableViewChainState[bucket] = fLargeCount; 227 fAttributes[index].next = null; 228 fAttributeTableView[bucket] = fAttributes[index]; 229 } 230 else { 233 Attribute found = fAttributeTableView[bucket]; 235 while (found != null) { 236 if (found.name.rawname == name.rawname) { 237 break; 238 } 239 found = found.next; 240 } 241 if (found == null) { 243 index = fLength; 244 if (fLength++ == fAttributes.length) { 245 Attribute[] attributes = new Attribute[fAttributes.length << 1]; 246 System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length); 247 for (int i = fAttributes.length; i < attributes.length; i++) { 248 attributes[i] = new Attribute(); 249 } 250 fAttributes = attributes; 251 } 252 253 fAttributes[index].next = fAttributeTableView[bucket]; 255 fAttributeTableView[bucket] = fAttributes[index]; 256 } 257 else { 259 index = getIndexFast(name.rawname); 260 } 261 } 262 } 263 264 Attribute attribute = fAttributes[index]; 266 attribute.name.setValues(name); 267 attribute.type = type; 268 attribute.value = value; 269 attribute.nonNormalizedValue = value; 270 attribute.specified = false; 271 272 attribute.augs.removeAllItems(); 274 275 return index; 276 277 } 279 283 public void removeAllAttributes() { 284 fLength = 0; 285 } 287 295 public void removeAttributeAt(int attrIndex) { 296 fIsTableViewConsistent = false; 297 if (attrIndex < fLength - 1) { 298 Attribute removedAttr = fAttributes[attrIndex]; 299 System.arraycopy(fAttributes, attrIndex + 1, 300 fAttributes, attrIndex, fLength - attrIndex - 1); 301 fAttributes[fLength-1] = removedAttr; 304 } 305 fLength--; 306 } 308 314 public void setName(int attrIndex, QName attrName) { 315 fAttributes[attrIndex].name.setValues(attrName); 316 } 318 325 public void getName(int attrIndex, QName attrName) { 326 attrName.setValues(fAttributes[attrIndex].name); 327 } 329 342 public void setType(int attrIndex, String attrType) { 343 fAttributes[attrIndex].type = attrType; 344 } 346 355 public void setValue(int attrIndex, String attrValue) { 356 Attribute attribute = fAttributes[attrIndex]; 357 attribute.value = attrValue; 358 attribute.nonNormalizedValue = attrValue; 359 } 361 368 public void setNonNormalizedValue(int attrIndex, String attrValue) { 369 if (attrValue == null) { 370 attrValue = fAttributes[attrIndex].value; 371 } 372 fAttributes[attrIndex].nonNormalizedValue = attrValue; 373 } 375 382 public String getNonNormalizedValue(int attrIndex) { 383 String value = fAttributes[attrIndex].nonNormalizedValue; 384 return value; 385 } 387 395 public void setSpecified(int attrIndex, boolean specified) { 396 fAttributes[attrIndex].specified = specified; 397 } 399 404 public boolean isSpecified(int attrIndex) { 405 return fAttributes[attrIndex].specified; 406 } 408 412 420 public int getLength() { 421 return fLength; 422 } 424 444 public String getType(int index) { 445 if (index < 0 || index >= fLength) { 446 return null; 447 } 448 return getReportableType(fAttributes[index].type); 449 } 451 462 public String getType(String qname) { 463 int index = getIndex(qname); 464 return index != -1 ? getReportableType(fAttributes[index].type) : null; 465 } 467 480 public String getValue(int index) { 481 if (index < 0 || index >= fLength) { 482 return null; 483 } 484 return fAttributes[index].value; 485 } 487 498 public String getValue(String qname) { 499 int index = getIndex(qname); 500 return index != -1 ? fAttributes[index].value : null; 501 } 503 507 523 public String getName(int index) { 524 if (index < 0 || index >= fLength) { 525 return null; 526 } 527 return fAttributes[index].name.rawname; 528 } 530 534 541 public int getIndex(String qName) { 542 for (int i = 0; i < fLength; i++) { 543 Attribute attribute = fAttributes[i]; 544 if (attribute.name.rawname != null && 545 attribute.name.rawname.equals(qName)) { 546 return i; 547 } 548 } 549 return -1; 550 } 552 561 public int getIndex(String uri, String localPart) { 562 for (int i = 0; i < fLength; i++) { 563 Attribute attribute = fAttributes[i]; 564 if (attribute.name.localpart != null && 565 attribute.name.localpart.equals(localPart) && 566 ((uri==attribute.name.uri) || 567 (uri!=null && attribute.name.uri!=null && attribute.name.uri.equals(uri)))) 568 { 569 return i; 570 } 571 } 572 return -1; 573 } 575 584 public String getLocalName(int index) { 585 if (!fNamespaces) { 586 return ""; 587 } 588 if (index < 0 || index >= fLength) { 589 return null; 590 } 591 return fAttributes[index].name.localpart; 592 } 594 603 public String getQName(int index) { 604 if (index < 0 || index >= fLength) { 605 return null; 606 } 607 String rawname = fAttributes[index].name.rawname; 608 return rawname != null ? rawname : ""; 609 } 611 624 public String getType(String uri, String localName) { 625 if (!fNamespaces) { 626 return null; 627 } 628 int index = getIndex(uri, localName); 629 return index != -1 ? getReportableType(fAttributes[index].type) : null; 630 } 632 637 public String getPrefix(int index) { 638 if (index < 0 || index >= fLength) { 639 return null; 640 } 641 String prefix = fAttributes[index].name.prefix; 642 return prefix != null ? prefix : ""; 644 } 646 653 public String getURI(int index) { 654 if (index < 0 || index >= fLength) { 655 return null; 656 } 657 String uri = fAttributes[index].name.uri; 658 return uri; 659 } 661 672 public String getValue(String uri, String localName) { 673 int index = getIndex(uri, localName); 674 return index != -1 ? getValue(index) : null; 675 } 677 678 685 public Augmentations getAugmentations (String uri, String localName) { 686 int index = getIndex(uri, localName); 687 return index != -1 ? fAttributes[index].augs : null; 688 } 689 690 699 public Augmentations getAugmentations(String qName){ 700 int index = getIndex(qName); 701 return index != -1 ? fAttributes[index].augs : null; 702 } 703 704 710 public Augmentations getAugmentations (int attributeIndex){ 711 if (attributeIndex < 0 || attributeIndex >= fLength) { 712 return null; 713 } 714 return fAttributes[attributeIndex].augs; 715 } 716 717 723 public void setAugmentations(int attrIndex, Augmentations augs) { 724 fAttributes[attrIndex].augs = augs; 725 } 726 727 733 public void setURI(int attrIndex, String uri) { 734 fAttributes[attrIndex].name.uri = uri; 735 } 737 public void setSchemaId(int attrIndex, boolean schemaId) { 739 fAttributes[attrIndex].schemaId = schemaId; 740 } 741 public boolean getSchemaId(int index) { 742 if (index < 0 || index >= fLength) { 743 return false; 744 } 745 return fAttributes[index].schemaId; 746 } 747 public boolean getSchemaId(String qname) { 748 int index = getIndex(qname); 749 return index != -1 ? fAttributes[index].schemaId : false; 750 } public boolean getSchemaId(String uri, String localName) { 752 if (!fNamespaces) { 753 return false; 754 } 755 int index = getIndex(uri, localName); 756 return index != -1 ? fAttributes[index].schemaId : false; 757 } 759 771 public int getIndexFast(String qName) { 772 for (int i = 0; i < fLength; ++i) { 773 Attribute attribute = fAttributes[i]; 774 if (attribute.name.rawname == qName) { 775 return i; 776 } 777 } 778 return -1; 779 } 781 808 public void addAttributeNS(QName name, String type, String value) { 809 int index = fLength; 810 if (fLength++ == fAttributes.length) { 811 Attribute[] attributes; 812 if (fLength < SIZE_LIMIT) { 813 attributes = new Attribute[fAttributes.length + 4]; 814 } 815 else { 816 attributes = new Attribute[fAttributes.length << 1]; 817 } 818 System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length); 819 for (int i = fAttributes.length; i < attributes.length; i++) { 820 attributes[i] = new Attribute(); 821 } 822 fAttributes = attributes; 823 } 824 825 Attribute attribute = fAttributes[index]; 827 attribute.name.setValues(name); 828 attribute.type = type; 829 attribute.value = value; 830 attribute.nonNormalizedValue = value; 831 attribute.specified = false; 832 833 attribute.augs.removeAllItems(); 835 } 836 837 849 public QName checkDuplicatesNS() { 850 if (fLength <= SIZE_LIMIT) { 852 for (int i = 0; i < fLength - 1; ++i) { 853 Attribute att1 = fAttributes[i]; 854 for (int j = i + 1; j < fLength; ++j) { 855 Attribute att2 = fAttributes[j]; 856 if (att1.name.localpart == att2.name.localpart && 857 att1.name.uri == att2.name.uri) { 858 return att2.name; 859 } 860 } 861 } 862 } 863 else { 865 fIsTableViewConsistent = false; 868 869 prepareTableView(); 870 871 Attribute attr; 872 int bucket; 873 874 for (int i = fLength - 1; i >= 0; --i) { 875 attr = fAttributes[i]; 876 bucket = getTableViewBucket(attr.name.localpart, attr.name.uri); 877 878 if (fAttributeTableViewChainState[bucket] != fLargeCount) { 881 fAttributeTableViewChainState[bucket] = fLargeCount; 882 attr.next = null; 883 fAttributeTableView[bucket] = attr; 884 } 885 else { 888 Attribute found = fAttributeTableView[bucket]; 890 while (found != null) { 891 if (found.name.localpart == attr.name.localpart && 892 found.name.uri == attr.name.uri) { 893 return attr.name; 894 } 895 found = found.next; 896 } 897 898 attr.next = fAttributeTableView[bucket]; 900 fAttributeTableView[bucket] = attr; 901 } 902 } 903 } 904 return null; 905 } 906 907 921 public int getIndexFast(String uri, String localPart) { 922 for (int i = 0; i < fLength; ++i) { 923 Attribute attribute = fAttributes[i]; 924 if (attribute.name.localpart == localPart && 925 attribute.name.uri == uri) { 926 return i; 927 } 928 } 929 return -1; 930 } 932 938 private String getReportableType(String type) { 939 940 if (type.charAt(0) == '(') { 941 return "NMTOKEN"; 942 } 943 return type; 944 } 945 946 954 protected int getTableViewBucket(String qname) { 955 return (qname.hashCode() & 0x7FFFFFFF) % fTableViewBuckets; 956 } 957 958 967 protected int getTableViewBucket(String localpart, String uri) { 968 if (uri == null) { 969 return (localpart.hashCode() & 0x7FFFFFFF) % fTableViewBuckets; 970 } 971 else { 972 return ((localpart.hashCode() + uri.hashCode()) 973 & 0x7FFFFFFF) % fTableViewBuckets; 974 } 975 } 976 977 980 protected void cleanTableView() { 981 if (++fLargeCount < 0) { 982 if (fAttributeTableViewChainState != null) { 984 for (int i = fTableViewBuckets - 1; i >= 0; --i) { 985 fAttributeTableViewChainState[i] = 0; 986 } 987 } 988 fLargeCount = 1; 989 } 990 } 991 992 995 protected void prepareTableView() { 996 if (fAttributeTableView == null) { 997 fAttributeTableView = new Attribute[fTableViewBuckets]; 998 fAttributeTableViewChainState = new int[fTableViewBuckets]; 999 } 1000 else { 1001 cleanTableView(); 1002 } 1003 } 1004 1005 1010 protected void prepareAndPopulateTableView() { 1011 prepareTableView(); 1012 Attribute attr; 1014 int bucket; 1015 for (int i = 0; i < fLength; ++i) { 1016 attr = fAttributes[i]; 1017 bucket = getTableViewBucket(attr.name.rawname); 1018 if (fAttributeTableViewChainState[bucket] != fLargeCount) { 1019 fAttributeTableViewChainState[bucket] = fLargeCount; 1020 attr.next = null; 1021 fAttributeTableView[bucket] = attr; 1022 } 1023 else { 1024 attr.next = fAttributeTableView[bucket]; 1026 fAttributeTableView[bucket] = attr; 1027 } 1028 } 1029 } 1030 1031 1035 1040 static class Attribute { 1041 1042 1046 1048 1049 public QName name = new QName(); 1050 1051 1052 public String type; 1053 1054 1055 public String value; 1056 1057 1058 public String nonNormalizedValue; 1059 1060 1061 public boolean specified; 1062 1063 1064 public boolean schemaId; 1065 1066 1071 public Augmentations augs = new AugmentationsImpl(); 1072 1073 1075 1076 public Attribute next; 1077 1078 } 1080} | Popular Tags |