1 21 22 package nu.xom; 23 24 import java.util.ArrayList ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.NoSuchElementException ; 28 import java.util.Set ; 29 import java.util.SortedSet ; 30 import java.util.TreeSet ; 31 32 52 public class Element extends ParentNode { 53 54 private String localName; 55 private String prefix; 56 private String URI; 57 58 private ArrayList attributes = null; 59 private Namespaces namespaces = null; 60 61 71 public Element(String name) { 72 this(name, ""); 73 } 74 75 76 91 public Element(String name, String uri) { 92 93 String prefix = ""; 96 String localName = name; 97 int colon = name.indexOf(':'); 98 if (colon > 0) { 99 prefix = name.substring(0, colon); 100 localName = name.substring(colon + 1); 101 } 102 103 _setNamespacePrefix(prefix); 106 _setNamespaceURI(uri); 107 try { 108 _setLocalName(localName); 109 } 110 catch (IllegalNameException ex) { 111 ex.setData(name); 112 throw ex; 113 } 114 115 } 116 117 118 private Element() {} 119 120 121 static Element build(String name, String uri) { 122 123 Element result = new Element(); 124 String prefix = ""; 125 String localName = name; 126 int colon = name.indexOf(':'); 127 if (colon >= 0) { 128 prefix = name.substring(0, colon); 129 localName = name.substring(colon + 1); 130 } 131 result.prefix = prefix; 132 result.localName = localName; 133 if (! "".equals(uri)) Verifier.checkAbsoluteURIReference(uri); 139 result.URI = uri; 140 return result; 141 142 } 143 144 145 155 public Element(Element element) { 156 157 this.prefix = element.prefix; 158 this.localName = element.localName; 159 this.URI = element.URI; 160 161 if (element.namespaces != null) { 163 this.namespaces = element.namespaces.copy(); 164 } 165 166 if (element.attributes != null) { 168 this.attributes = element.copyAttributes(); 169 } 170 171 this.actualBaseURI = element.findActualBaseURI(); 172 173 copyChildren(element, this); 174 175 } 176 177 178 private ArrayList copyAttributes() { 179 180 int size = attributes.size(); 181 ArrayList copy = new ArrayList (size); 182 for (int i = 0; i < size; i++) { 183 copy.add(((Attribute) attributes.get(i)).copy()); 184 } 185 return copy; 186 187 } 188 189 190 private static Element copyTag(final Element source) { 191 192 Element result = source.shallowCopy(); 193 194 if (source.namespaces != null) { 196 result.namespaces = source.namespaces.copy(); 197 } 198 199 if (source.attributes != null) { 201 result.attributes = source.copyAttributes(); 202 } 203 204 result.actualBaseURI = source.findActualBaseURI(); 205 206 return result; 207 208 } 209 210 211 private static void copyChildren(final Element sourceElement, 212 Element resultElement) { 213 214 if (sourceElement.getChildCount() == 0) return; 215 ParentNode resultParent = resultElement; 216 Node sourceCurrent = sourceElement; 217 int index = 0; 218 int[] indexes = new int[10]; 219 int top = 0; 220 indexes[0] = 0; 221 222 boolean endTag = false; 225 226 while (true) { 227 if (!endTag && sourceCurrent.getChildCount() > 0) { 228 sourceCurrent = sourceCurrent.getChild(0); 229 index = 0; 230 top++; 231 indexes = grow(indexes, top); 232 indexes[top] = 0; 233 } 234 else { 235 endTag = false; 236 ParentNode sourceParent = sourceCurrent.getParent(); 237 if (sourceParent.getChildCount() - 1 == index) { 238 sourceCurrent = sourceParent; 239 top--; 240 if (sourceCurrent == sourceElement) break; 241 resultParent = (Element) resultParent.getParent(); 243 index = indexes[top]; 244 endTag = true; 245 continue; 246 } 247 else { 248 index++; 249 indexes[top] = index; 250 sourceCurrent = sourceParent.getChild(index); 251 } 252 } 253 254 if (sourceCurrent.isElement()) { 255 Element child = copyTag((Element) sourceCurrent); 256 resultParent.appendChild(child); 257 if (sourceCurrent.getChildCount() > 0) { 258 resultParent = child; 259 } 260 } 261 else { 262 Node child = sourceCurrent.copy(); 263 resultParent.appendChild(child); 264 } 265 266 } 267 268 } 269 270 271 private static int[] grow(int[] indexes, int top) { 272 273 if (top < indexes.length) return indexes; 274 int[] result = new int[indexes.length*2]; 275 System.arraycopy(indexes, 0, result, 0, indexes.length); 276 return result; 277 278 } 279 280 281 293 public final Elements getChildElements(String name) { 294 return getChildElements(name, ""); 295 } 296 297 298 317 public final Elements getChildElements(String localName, 318 String namespaceURI) { 319 320 if (namespaceURI == null) namespaceURI = ""; 321 if (localName == null) localName = ""; 322 323 Elements elements = new Elements(); 324 for (int i = 0; i < getChildCount(); i++) { 325 Node child = getChild(i); 326 if (child.isElement()) { 327 Element element = (Element) child; 328 if ((localName.equals(element.getLocalName()) 329 || localName.length() == 0) 330 && namespaceURI.equals(element.getNamespaceURI())) { 331 elements.add(element); 332 } 333 } 334 } 335 return elements; 336 337 } 338 339 340 349 public final Elements getChildElements() { 350 351 Elements elements = new Elements(); 352 for (int i = 0; i < getChildCount(); i++) { 353 Node child = getChild(i); 354 if (child.isElement()) { 355 Element element = (Element) child; 356 elements.add(element); 357 } 358 } 359 return elements; 360 361 } 362 363 364 376 public final Element getFirstChildElement(String name) { 377 return getFirstChildElement(name, ""); 378 } 379 380 381 394 public final Element getFirstChildElement(String localName, 395 String namespaceURI) { 396 397 for (int i = 0; i < getChildCount(); i++) { 398 Node child = getChild(i); 399 if (child.isElement()) { 400 Element element = (Element) child; 401 if (localName.equals(element.getLocalName()) 402 && namespaceURI.equals(element.getNamespaceURI())) { 403 return element; 404 } 405 } 406 } 407 return null; 408 409 } 410 411 412 428 public void addAttribute(Attribute attribute) { 429 430 if (attribute.getParent() != null) { 431 throw new MultipleParentException( 432 "Attribute already has a parent"); 433 } 434 435 String attPrefix = attribute.getNamespacePrefix(); 437 if (attPrefix.length() != 0 && !"xml".equals(attPrefix)) { 438 if (prefix.equals(attribute.getNamespacePrefix()) 439 && !(getNamespaceURI() 440 .equals(attribute.getNamespaceURI()))) { 441 throw new NamespaceConflictException("Prefix of " 442 + attribute.getQualifiedName() 443 + " conflicts with element prefix " + prefix); 444 } 445 if (namespaces != null) { 447 String existing 448 = namespaces.getURI(attribute.getNamespacePrefix()); 449 if (existing != null 450 && !existing.equals(attribute.getNamespaceURI())) { 451 throw new NamespaceConflictException("Attribute prefix " 452 + attPrefix 453 + " conflicts with namespace declaration."); 454 } 455 } 456 457 } 458 459 if (attributes == null) attributes = new ArrayList (1); 460 checkPrefixConflict(attribute); 461 462 Attribute oldAttribute = getAttribute(attribute.getLocalName(), 465 attribute.getNamespaceURI()); 466 if (oldAttribute != null) attributes.remove(oldAttribute); 467 468 attributes.add(attribute); 469 attribute.setParent(this); 470 471 } 472 473 474 void fastAddAttribute(Attribute attribute) { 475 if (attributes == null) attributes = new ArrayList (1); 476 attributes.add(attribute); 477 attribute.setParent(this); 478 } 479 480 481 494 public Attribute removeAttribute(Attribute attribute) { 495 496 if (attributes == null) { 497 throw new NoSuchAttributeException( 498 "Tried to remove attribute " 499 + attribute.getQualifiedName() 500 + " from non-parent element"); 501 } 502 if (attribute == null) { 503 throw new NullPointerException ( 504 "Tried to remove null attribute"); 505 } 506 if (attributes.remove(attribute)) { 507 attribute.setParent(null); 508 return attribute; 509 } 510 else { 511 throw new NoSuchAttributeException( 512 "Tried to remove attribute " 513 + attribute.getQualifiedName() 514 + " from non-parent element"); 515 } 516 517 } 518 519 520 531 public final Attribute getAttribute(String name) { 532 return getAttribute(name, ""); 533 } 534 535 536 549 public final Attribute getAttribute(String localName, 550 String namespaceURI) { 551 552 if (attributes == null) return null; 553 int size = attributes.size(); 554 for (int i = 0; i < size; i++) { 555 Attribute a = (Attribute) attributes.get(i); 556 if (a.getLocalName().equals(localName) 557 && a.getNamespaceURI().equals(namespaceURI)) { 558 return a; 559 } 560 } 561 562 return null; 563 564 } 565 566 567 580 public final String getAttributeValue(String name) { 581 return getAttributeValue(name, ""); 582 } 583 584 585 595 public final int getAttributeCount() { 596 if (attributes == null) return 0; 597 return attributes.size(); 598 } 599 600 601 631 public final Attribute getAttribute(int index) { 632 633 if (attributes == null) { 634 throw new IndexOutOfBoundsException ( 635 "Element does not have any attributes" 636 ); 637 } 638 return (Attribute) attributes.get(index); 639 640 } 641 642 643 656 public final String getAttributeValue(String localName, 657 String namespaceURI) { 658 659 Attribute attribute = getAttribute(localName, namespaceURI); 660 if (attribute == null) return null; 661 else return attribute.getValue(); 662 663 } 664 665 666 674 public final String getLocalName() { 675 return localName; 676 } 677 678 679 687 public final String getQualifiedName() { 688 if (prefix.length() == 0) return localName; 689 else return prefix + ":" + localName; 690 } 691 692 693 701 public final String getNamespacePrefix() { 702 return prefix; 703 } 704 705 706 715 public final String getNamespaceURI() { 716 return URI; 717 } 718 719 720 731 public final String getNamespaceURI(String prefix) { 732 733 Element current = this; 734 String result = getLocalNamespaceURI(prefix); 735 while (result == null) { 736 ParentNode parent = current.getParent(); 737 if (parent == null || parent.isDocument()) break; 738 current = (Element) parent; 739 result = current.getLocalNamespaceURI(prefix); 740 } 741 if (result == null && "".equals(prefix)) result = ""; 742 return result; 743 744 } 745 746 747 String getLocalNamespaceURI(String prefix) { 748 749 if (prefix.equals(this.prefix)) return this.URI; 750 751 if ("xml".equals(prefix)) { 752 return "http://www.w3.org/XML/1998/namespace"; 753 } 754 if ("xmlns".equals(prefix)) return ""; 758 if (namespaces != null) { 760 String result = namespaces.getURI(prefix); 761 if (result != null) return result; 762 } 763 if (prefix.length() != 0 && attributes != null) { 765 for (int i = 0; i < attributes.size(); i++) { 766 Attribute a = (Attribute) attributes.get(i); 767 if (a.getNamespacePrefix().equals(prefix)) { 768 return a.getNamespaceURI(); 769 } 770 } 771 } 772 773 return null; 774 775 } 776 777 778 788 public void setLocalName(String localName) { 789 _setLocalName(localName); 790 } 791 792 793 private void _setLocalName(String localName) { 794 Verifier.checkNCName(localName); 795 this.localName = localName; 796 } 797 798 799 813 public void setNamespaceURI(String uri) { 814 _setNamespaceURI(uri); 815 } 816 817 818 private void _setNamespaceURI(String uri) { 819 820 if (uri == null) uri = ""; 821 if (uri.equals(this.URI)) return; 824 if (uri.length() == 0) { if (prefix.length() != 0) { 826 throw new NamespaceConflictException( 827 "Prefixed elements must have namespace URIs." 828 ); 829 } 830 } 831 else Verifier.checkAbsoluteURIReference(uri); 832 if (namespaces != null) { 839 String result = namespaces.getURI(prefix); 840 if (result != null) { 841 throw new NamespaceConflictException( 842 "new URI conflicts with existing prefix" 843 ); 844 } 845 } 846 if (uri.length() > 0 && attributes != null) { 848 for (int i = 0; i < attributes.size(); i++) { 849 Attribute a = (Attribute) attributes.get(i); 850 String attPrefix = a.getNamespacePrefix(); 851 if (attPrefix.length() == 0) continue; 852 if (a.getNamespacePrefix().equals(prefix)) { 853 throw new NamespaceConflictException( 854 "new element URI " + uri 855 + " conflicts with attribute " 856 + a.getQualifiedName() 857 ); 858 } 859 } 860 } 861 862 if ("http://www.w3.org/XML/1998/namespace".equals(uri) 863 && ! "xml".equals(prefix)) { 864 throw new NamespaceConflictException( 865 "Wrong prefix " + prefix + 866 " for the http://www.w3.org/XML/1998/namespace namespace URI" 867 ); 868 } 869 else if ("xml".equals(prefix) && 870 !"http://www.w3.org/XML/1998/namespace".equals(uri)) { 871 throw new NamespaceConflictException( 872 "Wrong namespace URI " + uri + " for the xml prefix" 873 ); 874 } 875 876 this.URI = uri; 877 878 } 879 880 881 896 public void setNamespacePrefix(String prefix) { 897 _setNamespacePrefix(prefix); 898 } 899 900 901 private void _setNamespacePrefix(String prefix) { 902 903 if (prefix == null) prefix = ""; 904 if (prefix.length() != 0) Verifier.checkNCName(prefix); 905 906 String uri = getLocalNamespaceURI(prefix); 910 if (uri != null) { 911 if (!uri.equals(this.URI) && !"xml".equals(prefix)) { 912 throw new NamespaceConflictException(prefix 913 + " conflicts with existing prefix"); 914 } 915 } 916 else if ("".equals(this.URI) && !"".equals(prefix)) { 917 throw new NamespaceConflictException( 918 "Cannot assign prefix to element in no namespace"); 919 } 920 921 this.prefix = prefix; 922 923 } 924 925 926 951 void insertionAllowed(Node child, int position) { 952 953 if (child == null) { 954 throw new NullPointerException ( 955 "Tried to insert a null child in the tree"); 956 } 957 else if (child.getParent() != null) { 958 throw new MultipleParentException(child.toString() 959 + " child already has a parent."); 960 } 961 else if (child.isElement()) { 962 checkCycle(child, this); 963 return; 964 } 965 else if (child.isText() 966 || child.isProcessingInstruction() 967 || child.isComment()) { 968 return; 969 } 970 else { 971 throw new IllegalAddException("Cannot add a " 972 + child.getClass().getName() + " to an Element."); 973 } 974 975 } 976 977 978 private static void checkCycle(Node child, ParentNode parent) { 979 980 if (child == parent) { 981 throw new CycleException("Cannot add a node to itself"); 982 } 983 if (child.getChildCount() == 0) return; 984 while ((parent = parent.getParent()) != null) { 985 if (parent == child) { 986 throw new CycleException( 987 "Cannot add an ancestor as a child"); 988 } 989 } 990 return; 991 992 } 993 994 995 1008 public void insertChild(String text, int position) { 1009 1010 if (text == null) { 1011 throw new NullPointerException ("Inserted null string"); 1012 } 1013 super.fastInsertChild(new Text(text), position); 1014 1015 } 1016 1017 1018 1030 public void appendChild(String text) { 1031 insertChild(new Text(text), getChildCount()); 1032 } 1033 1034 1035 1051 public Nodes removeChildren() { 1052 1053 int length = this.getChildCount(); 1054 Nodes result = new Nodes(); 1055 for (int i = 0; i < length; i++) { 1056 Node child = getChild(i); 1057 if (child.isElement()) fillInBaseURI((Element) child); 1058 child.setParent(null); 1059 result.append(child); 1060 } 1061 this.children = null; 1062 1063 return result; 1064 1065 } 1066 1067 1068 1095 public void addNamespaceDeclaration(String prefix, String uri) { 1096 1097 if (prefix == null) prefix = ""; 1098 if (uri == null) uri = ""; 1099 1100 if (prefix.equals("xmlns")) { 1102 if (uri.equals("")) { 1103 return; 1105 } 1106 throw new NamespaceConflictException( 1107 "The xmlns prefix cannot bound to any URI"); 1108 } 1109 else if (prefix.equals("xml")) { 1110 if (uri.equals("http://www.w3.org/XML/1998/namespace")) { 1111 return; 1113 } 1114 throw new NamespaceConflictException( 1115 "Wrong namespace URI for xml prefix: " + uri); 1116 } 1117 else if (uri.equals("http://www.w3.org/XML/1998/namespace")) { 1118 throw new NamespaceConflictException( 1119 "Wrong prefix for http://www.w3.org/XML/1998/namespace namespace: " 1120 + prefix); 1121 } 1122 1123 if (prefix.length() != 0) { 1124 Verifier.checkNCName(prefix); 1125 Verifier.checkAbsoluteURIReference(uri); 1126 } 1127 else if (uri.length() != 0) { 1128 Verifier.checkAbsoluteURIReference(uri); 1131 } 1132 1133 String currentBinding = getLocalNamespaceURI(prefix); 1134 if (currentBinding != null && !currentBinding.equals(uri)) { 1135 throw new NamespaceConflictException( 1136 "Additional namespace " + uri 1137 + " conflicts with existing namespace binding." 1138 ); 1139 } 1140 1141 if (namespaces == null) namespaces = new Namespaces(); 1142 namespaces.put(prefix, uri); 1143 1144 } 1145 1146 1147 1159 public void removeNamespaceDeclaration(String prefix) { 1160 1161 if (namespaces != null) { 1162 namespaces.remove(prefix); 1163 } 1164 1165 } 1166 1167 1168 1194 public final int getNamespaceDeclarationCount() { 1195 1196 Set allPrefixes = null; 1204 if (namespaces != null) { 1205 allPrefixes = new HashSet (namespaces.getPrefixes()); 1206 allPrefixes.add(prefix); 1207 } 1208 if ("xml".equals(prefix)) allPrefixes = new HashSet (); 1209 int count = getAttributeCount(); 1211 for (int i = 0; i < count; i++) { 1212 Attribute att = getAttribute(i); 1213 String attPrefix = att.getNamespacePrefix(); 1214 if (attPrefix.length() != 0 && !"xml".equals(attPrefix)) { 1215 if (allPrefixes == null) { 1216 allPrefixes = new HashSet (); 1217 allPrefixes.add(prefix); 1218 } 1219 allPrefixes.add(attPrefix); 1220 } 1221 } 1222 1223 if (allPrefixes == null) return 1; 1224 return allPrefixes.size(); 1225 1226 } 1227 1228 1229 1261 public final String getNamespacePrefix(int index) { 1262 1263 SortedSet allPrefixes; 1264 if (namespaces != null) { 1265 allPrefixes = new TreeSet (namespaces.getPrefixes()); 1266 } 1267 else allPrefixes = new TreeSet (); 1268 1269 if (!("xml".equals(prefix))) allPrefixes.add(prefix); 1270 1271 for (int i = 0; i < getAttributeCount(); i++) { 1273 Attribute att = getAttribute(i); 1274 String attPrefix = att.getNamespacePrefix(); 1275 if (attPrefix.length() != 0 && !("xml".equals(attPrefix))) { 1276 allPrefixes.add(attPrefix); 1277 } 1278 } 1279 1280 Iterator iterator = allPrefixes.iterator(); 1281 try { 1282 for (int i = 0; i < index; i++) { 1283 iterator.next(); 1284 } 1285 return (String ) iterator.next(); 1286 } 1287 catch (NoSuchElementException ex) { 1288 throw new IndexOutOfBoundsException ( 1289 "No " + index + "th namespace"); 1290 } 1291 1292 } 1293 1294 1295 1310 public void setBaseURI(String URI) { 1311 setActualBaseURI(URI); 1312 } 1313 1314 1315 1344 public String getBaseURI() { 1345 1346 String baseURI = ""; 1347 String sourceEntity = this.getActualBaseURI(); 1348 1349 ParentNode current = this; 1350 1351 while (true) { 1352 String currentEntity = current.getActualBaseURI(); 1353 if (sourceEntity.length() != 0 1354 && ! sourceEntity.equals(currentEntity)) { 1355 baseURI = URIUtil.absolutize(sourceEntity, baseURI); 1356 break; 1357 } 1358 1359 if (current.isDocument()) { 1360 baseURI = URIUtil.absolutize(currentEntity, baseURI); 1361 break; 1362 } 1363 Attribute baseAttribute = ((Element) current).getAttribute("base", 1364 "http://www.w3.org/XML/1998/namespace"); 1365 if (baseAttribute != null) { 1366 String baseIRI = baseAttribute.getValue(); 1367 String base = URIUtil.toURI(baseIRI); 1371 if ("".equals(base)) { 1372 baseURI = getEntityURI(); 1373 break; 1374 } 1375 else if (legalURI(base)) { 1376 if ("".equals(baseURI)) baseURI = base; 1377 else if (URIUtil.isOpaque(base)) break; 1378 else baseURI = URIUtil.absolutize(base, baseURI); 1379 if (URIUtil.isAbsolute(base)) break; 1380 } 1381 } 1382 current = current.getParent(); 1383 if (current == null) { 1384 baseURI = URIUtil.absolutize(currentEntity, baseURI); 1385 break; 1386 } 1387 } 1388 1389 if (URIUtil.isAbsolute(baseURI)) return baseURI; 1390 return ""; 1391 1392 } 1393 1394 1395 private String getEntityURI() { 1396 1397 ParentNode current = this; 1398 while (current != null) { 1399 if (current.actualBaseURI != null 1400 && current.actualBaseURI.length() != 0) { 1401 return current.actualBaseURI; 1402 } 1403 current = current.getParent(); 1404 } 1405 return ""; 1406 1407 } 1408 1409 1410 private boolean legalURI(String base) { 1411 1412 try { 1413 Verifier.checkURIReference(base); 1414 return true; 1415 } 1416 catch (MalformedURIException ex) { 1417 return false; 1418 } 1419 1420 } 1421 1422 1423 1434 public final String toXML() { 1435 1436 StringBuffer result = new StringBuffer (1024); 1437 Node current = this; 1438 boolean endTag = false; 1439 int index = -1; 1440 int[] indexes = new int[10]; 1441 int top = 0; 1442 indexes[0] = -1; 1443 1444 while (true) { 1445 1446 if (!endTag && current.getChildCount() > 0) { 1447 writeStartTag((Element) current, result); 1448 current = current.getChild(0); 1449 index = 0; 1450 top++; 1451 indexes = grow(indexes, top); 1452 indexes[top] = 0; 1453 } 1454 else { 1455 if (endTag) { 1456 writeEndTag((Element) current, result); 1457 if (current == this) break; 1458 } 1459 else if (current.isElement()) { 1460 writeStartTag((Element) current, result); 1461 if (current == this) break; 1462 } 1463 else { 1464 result.append(current.toXML()); 1465 } 1466 endTag = false; 1467 ParentNode parent = current.getParent(); 1468 if (parent.getChildCount() - 1 == index) { 1469 current = parent; 1470 top--; 1471 if (current != this) { 1472 parent = current.getParent(); 1473 index = indexes[top]; 1474 } 1475 endTag = true; 1476 } 1477 else { 1478 index++; 1479 indexes[top] = index; 1480 current = parent.getChild(index); 1481 } 1482 1483 } 1484 1485 } 1486 1487 return result.toString(); 1488 1489 } 1490 1491 1492 private static void writeStartTag(Element element, StringBuffer result) { 1493 1494 result.append("<"); 1495 result.append(element.getQualifiedName()); 1496 1497 ParentNode parentNode = element.getParent(); 1498 for (int i = 0; i < element.getNamespaceDeclarationCount(); i++) { 1499 String additionalPrefix = element.getNamespacePrefix(i); 1500 String uri = element.getNamespaceURI(additionalPrefix); 1501 if (parentNode != null && parentNode.isElement()) { 1502 Element parentElement = (Element) parentNode; 1503 if (uri.equals( 1504 parentElement.getNamespaceURI(additionalPrefix))) { 1505 continue; 1506 } 1507 } 1508 else if (uri.length() == 0) { 1509 continue; } 1511 1512 result.append(" xmlns"); 1513 if (additionalPrefix.length() > 0) { 1514 result.append(':'); 1515 result.append(additionalPrefix); 1516 } 1517 result.append("=\""); 1518 result.append(uri); 1519 result.append('"'); 1520 } 1521 1522 if (element.attributes != null) { 1524 for (int i = 0; i < element.attributes.size(); i++) { 1525 Attribute attribute = (Attribute) element.attributes.get(i); 1526 result.append(' '); 1527 result.append(attribute.toXML()); 1528 } 1529 } 1530 1531 if (element.getChildCount() > 0) { 1532 result.append('>'); 1533 } 1534 else { 1535 result.append(" />"); 1536 } 1537 1538 } 1539 1540 1541 private static void writeEndTag( 1542 Element element, StringBuffer result) { 1543 1544 result.append("</"); 1545 result.append(element.getQualifiedName()); 1546 result.append(">"); 1547 1548 } 1549 1550 1551 1562 public final String getValue() { 1563 1564 if (this.getChildCount() == 0) return ""; 1566 StringBuffer result = new StringBuffer (); 1567 Node current = this.getChild(0); 1568 int index = 0; 1569 int[] indexes = new int[10]; 1570 int top = 0; 1571 indexes[0] = 0; 1572 1573 boolean endTag = false; 1574 while (true) { 1575 if (!endTag && current.getChildCount() > 0) { 1576 current = current.getChild(0); 1577 index = 0; 1578 top++; 1579 indexes = grow(indexes, top); 1580 indexes[top] = 0; } 1581 else { 1582 endTag = false; 1583 if (current.isText()) result.append(current.getValue()); 1584 ParentNode parent = current.getParent(); 1585 if (parent.getChildCount() - 1 == index) { 1586 current = parent; 1587 top--; 1588 if (current == this) break; 1589 index = indexes[top]; 1590 endTag = true; 1591 } 1592 else { 1593 index++; 1594 indexes[top] = index; 1595 current = parent.getChild(index); 1596 } 1597 } 1598 } 1599 1600 return result.toString(); 1601 1602 } 1603 1604 1621 public Node copy() { 1622 Element result = copyTag(this); 1623 copyChildren(this, result); 1624 return result; 1625 } 1626 1627 1628 1649 protected Element shallowCopy() { 1650 return new Element(getQualifiedName(), getNamespaceURI()); 1651 } 1652 1653 1654 1663 public final String toString() { 1664 return 1665 "[" + getClass().getName() + ": " + getQualifiedName() + "]"; 1666 } 1667 1668 1669 boolean isElement() { 1670 return true; 1671 } 1672 1673 1674 private void checkPrefixConflict(Attribute attribute) { 1675 1676 String prefix = attribute.getNamespacePrefix(); 1677 String namespaceURI = attribute.getNamespaceURI(); 1678 1679 int size = attributes.size(); 1681 for (int i = 0; i < size; i++) { 1682 Attribute a = (Attribute) attributes.get(i); 1683 if (a.getNamespacePrefix().equals(prefix)) { 1684 if (a.getNamespaceURI().equals(namespaceURI)) return; 1685 throw new NamespaceConflictException( 1686 "Prefix of " + attribute.getQualifiedName() 1687 + " conflicts with " + a.getQualifiedName()); 1688 } 1689 } 1690 1691 } 1692 1693 1694} | Popular Tags |