1:
37:
38: package ;
39:
40: import ;
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69:
70:
82: public class DomDocument
83: extends DomNode
84: implements Document, DocumentTraversal, XPathEvaluator
85: {
86:
87: private final DOMImplementation implementation;
88: private boolean checkingCharacters = true;
89: boolean checkingWellformedness = true;
90: private boolean defaultAttributes = true;
91:
92: boolean building;
93:
94: DomDocumentConfiguration config;
95:
96: String inputEncoding;
97: String encoding;
98: String version = "1.0";
99: boolean standalone;
100: String systemId;
101:
102:
114: public DomDocument()
115: {
116: this(new DomImpl());
117: }
118:
119:
128: protected DomDocument(DOMImplementation impl)
129: {
130: super(DOCUMENT_NODE, null);
131: implementation = impl;
132: }
133:
134:
138: public void setBuilding(boolean flag)
139: {
140: building = flag;
141: }
142:
143:
148: public void setCheckWellformedness(boolean flag)
149: {
150: checkingWellformedness = flag;
151: }
152:
153:
156: public void setCheckingCharacters(boolean flag)
157: {
158: checkingCharacters = flag;
159: }
160:
161:
164: public void setDefaultAttributes(boolean flag)
165: {
166: defaultAttributes = flag;
167: }
168:
169:
173: final public String getNodeName()
174: {
175: return "#document";
176: }
177:
178:
182: final public Element getDocumentElement()
183: {
184: for (DomNode ctx = first; ctx != null; ctx = ctx.next)
185: {
186: if (ctx.nodeType == ELEMENT_NODE)
187: {
188: return (Element) ctx;
189: }
190: }
191: return null;
192: }
193:
194:
198: final public DocumentType getDoctype()
199: {
200: for (DomNode ctx = first; ctx != null; ctx = ctx.next)
201: {
202: if (ctx.nodeType == DOCUMENT_TYPE_NODE)
203: {
204: return (DocumentType) ctx;
205: }
206: }
207: return null;
208: }
209:
210:
214: final public DOMImplementation getImplementation()
215: {
216: return implementation;
217: }
218:
219:
228: public Element getElementById(String id)
229: {
230: if (id == null || id.length() == 0)
231: {
232: return null;
233: }
234: DomDoctype doctype = (DomDoctype) getDoctype();
235: if (doctype != null && !doctype.hasIds())
236: {
237: doctype = null;
238: }
239:
240:
241:
242: Node current = getDocumentElement();
243: Node temp;
244:
245: if (current == null)
246: {
247: return null;
248: }
249: while (current != this)
250: {
251:
252: if (current.getNodeType() == ELEMENT_NODE)
253: {
254: DomElement element = (DomElement) current;
255: if (element.userIdAttrs != null)
256: {
257: for (Iterator i = element.userIdAttrs.iterator();
258: i.hasNext(); )
259: {
260: Node idAttr = (Node) i.next();
261: if (id.equals(idAttr.getNodeValue()))
262: {
263: return element;
264: }
265: }
266: }
267: if (doctype != null)
268: {
269: DTDElementTypeInfo info =
270: doctype.getElementTypeInfo(current.getNodeName());
271: if (info != null &&
272: id.equals(element.getAttribute(info.idAttrName)))
273: {
274: return element;
275: }
276: }
277:
278: String xmlId = element.getAttribute("xml:id");
279: if (xmlId == null)
280: {
281: xmlId = element.getAttributeNS(XMLConstants.XML_NS_URI,
282: "id");
283: }
284: if (id.equals(xmlId))
285: {
286: return element;
287: }
288: }
289:
290:
291: if (current.hasChildNodes())
292: {
293: current = current.getFirstChild();
294: continue;
295: }
296:
297:
298: temp = current.getNextSibling();
299: if (temp != null)
300: {
301: current = temp;
302: continue;
303: }
304:
305:
306: do
307: {
308: temp = current.getParentNode();
309: if (temp == null)
310: {
311: return null;
312: }
313: current = temp;
314: temp = current.getNextSibling();
315: }
316: while (temp == null);
317: current = temp;
318: }
319: return null;
320: }
321:
322: private void checkNewChild(Node newChild)
323: {
324: if (newChild.getNodeType() == ELEMENT_NODE
325: && getDocumentElement() != null)
326: {
327: throw new DomDOMException(DOMException.HIERARCHY_REQUEST_ERR,
328: "document element already present: " +
329: getDocumentElement(), newChild, 0);
330: }
331: if (newChild.getNodeType() == DOCUMENT_TYPE_NODE
332: && getDoctype() != null)
333: {
334: throw new DomDOMException(DOMException.HIERARCHY_REQUEST_ERR,
335: "document type already present: " +
336: getDoctype(), newChild, 0);
337: }
338: }
339:
340:
346: public Node appendChild(Node newChild)
347: {
348: if (checkingWellformedness)
349: {
350: checkNewChild(newChild);
351: }
352: return super.appendChild(newChild);
353: }
354:
355:
361: public Node insertBefore(Node newChild, Node refChild)
362: {
363: if (checkingWellformedness)
364: {
365: checkNewChild(newChild);
366: }
367: return super.insertBefore(newChild, refChild);
368: }
369:
370:
376: public Node replaceChild(Node newChild, Node refChild)
377: {
378: if (checkingWellformedness &&
379: ((newChild.getNodeType() == ELEMENT_NODE &&
380: refChild.getNodeType() != ELEMENT_NODE) ||
381: (newChild.getNodeType() == DOCUMENT_TYPE_NODE &&
382: refChild.getNodeType() != DOCUMENT_TYPE_NODE)))
383: {
384: checkNewChild(newChild);
385: }
386: return super.replaceChild(newChild, refChild);
387: }
388:
389:
390:
391:
392:
393:
394:
395:
401: public static void verifyXmlName(String name)
402: {
403:
404: checkName(name, false);
405: }
406:
407: static void checkName(String name, boolean xml11)
408: {
409: if (name == null)
410: {
411: throw new DomDOMException(DOMException.NAMESPACE_ERR, name, null, 0);
412: }
413: int len = name.length();
414: if (len == 0)
415: {
416: throw new DomDOMException(DOMException.NAMESPACE_ERR, name, null, 0);
417: }
418:
419:
420:
421:
422: char c = name.charAt(0);
423: if (xml11)
424: {
425:
426: if ((c < 0x0041 || c > 0x005a) &&
427: (c < 0x0061 || c > 0x007a) &&
428: c != ':' && c != '_' &&
429: (c < 0x00c0 || c > 0x00d6) &&
430: (c < 0x00d8 || c > 0x00f6) &&
431: (c < 0x00f8 || c > 0x02ff) &&
432: (c < 0x0370 || c > 0x037d) &&
433: (c < 0x037f || c > 0x1fff) &&
434: (c < 0x200c || c > 0x200d) &&
435: (c < 0x2070 || c > 0x218f) &&
436: (c < 0x2c00 || c > 0x2fef) &&
437: (c < 0x3001 || c > 0xd7ff) &&
438: (c < 0xf900 || c > 0xfdcf) &&
439: (c < 0xfdf0 || c > 0xfffd) &&
440: (c < 0x10000 || c > 0xeffff))
441: {
442: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
443: name, null, c);
444: }
445: }
446: else
447: {
448:
449: int type = Character.getType(c);
450: switch (type)
451: {
452: case Character.LOWERCASE_LETTER:
453: case Character.UPPERCASE_LETTER:
454: case Character.OTHER_LETTER:
455: case Character.TITLECASE_LETTER:
456: case Character.LETTER_NUMBER:
457: if ((c > 0xf900 && c < 0xfffe) ||
458: (c >= 0x20dd && c <= 0x20e0))
459: {
460:
461: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
462: name, null, c);
463: }
464: break;
465: default:
466: if (c != ':' && c != '_' && (c < 0x02bb || c > 0x02c1) &&
467: c != 0x0559 && c != 0x06e5 && c != 0x06e6)
468: {
469: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
470: name, null, c);
471: }
472: }
473: }
474:
475:
476: for (int i = 1; i < len; i++)
477: {
478: c = name.charAt(i);
479: if (xml11)
480: {
481:
482: if ((c < 0x0041 || c > 0x005a) &&
483: (c < 0x0061 || c > 0x007a) &&
484: (c < 0x0030 || c > 0x0039) &&
485: c != ':' && c != '_' && c != '-' && c != '.' &&
486: (c < 0x00c0 || c > 0x00d6) &&
487: (c < 0x00d8 || c > 0x00f6) &&
488: (c < 0x00f8 || c > 0x02ff) &&
489: (c < 0x0370 || c > 0x037d) &&
490: (c < 0x037f || c > 0x1fff) &&
491: (c < 0x200c || c > 0x200d) &&
492: (c < 0x2070 || c > 0x218f) &&
493: (c < 0x2c00 || c > 0x2fef) &&
494: (c < 0x3001 || c > 0xd7ff) &&
495: (c < 0xf900 || c > 0xfdcf) &&
496: (c < 0xfdf0 || c > 0xfffd) &&
497: (c < 0x10000 || c > 0xeffff) &&
498: c != 0x00b7 &&
499: (c < 0x0300 || c > 0x036f) &&
500: (c < 0x203f || c > 0x2040))
501: {
502: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR, name,
503: null, c);
504: }
505: }
506: else
507: {
508:
509: int type = Character.getType(c);
510: switch (type)
511: {
512: case Character.LOWERCASE_LETTER:
513: case Character.UPPERCASE_LETTER:
514: case Character.DECIMAL_DIGIT_NUMBER:
515: case Character.OTHER_LETTER:
516: case Character.TITLECASE_LETTER:
517: case Character.LETTER_NUMBER:
518: case Character.COMBINING_SPACING_MARK:
519: case Character.ENCLOSING_MARK:
520: case Character.NON_SPACING_MARK:
521: case Character.MODIFIER_LETTER:
522: if ((c > 0xf900 && c < 0xfffe) ||
523: (c >= 0x20dd && c <= 0x20e0))
524: {
525:
526: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
527: name, null, c);
528: }
529: break;
530: default:
531: if (c != '-' && c != '.' && c != ':' && c != '_' &&
532: c != 0x0387 && (c < 0x02bb || c > 0x02c1) &&
533: c != 0x0559 && c != 0x06e5 && c != 0x06e6 && c != 0x00b7)
534: {
535: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
536: name, null, c);
537: }
538: }
539: }
540: }
541:
542:
543:
544:
545: }
546:
547:
548: static void checkNCName(String name, boolean xml11)
549: {
550: checkName(name, xml11);
551: int len = name.length();
552: int index = name.indexOf(':');
553: if (index != -1)
554: {
555: if (index == 0 || index == (len - 1) || name.lastIndexOf(':') != index)
556: {
557: throw new DomDOMException(DOMException.NAMESPACE_ERR, name, null, 0);
558: }
559: }
560: }
561:
562:
563: static void checkChar(String value, boolean xml11)
564: {
565: char[] chars = value.toCharArray();
566: checkChar(chars, 0, chars.length, xml11);
567: }
568:
569: static void checkChar(char[] buf, int off, int len, boolean xml11)
570: {
571: for (int i = 0; i < len; i++)
572: {
573: char c = buf[i];
574:
575:
576: if ((c >= 0x0020 && c <= 0xd7ff) ||
577: (c == 0x000a || c == 0x000d || c == 0x0009) ||
578: (c >= 0xe000 && c <= 0xfffd) ||
579: (c >= 0x10000 && c <= 0x10ffff))
580: {
581: continue;
582: }
583: if (xml11)
584: {
585: if ((c >= 0x0001 && c <= 0x001f) ||
586: (c >= 0x007f && c <= 0x0084) ||
587: (c >= 0x0086 && c <= 0x009f))
588: {
589: continue;
590: }
591: }
592: throw new DomDOMException(DOMException.INVALID_CHARACTER_ERR,
593: new String(buf, off, len), null, c);
594: }
595: }
596:
597:
603: public Element createElement(String name)
604: {
605: Element element;
606:
607: if (checkingCharacters)
608: {
609: checkName(name, "1.1".equals(version));
610: }
611: if (name.startsWith("xml:"))
612: {
613: element = createElementNS(null, name);
614: }
615: else
616: {
617: DomElement domElement = new DomElement(this, null, name, null, null);
618: element = domElement;
619: }
620: if (defaultAttributes)
621: setDefaultAttributes(element, name);
622: return element;
623: }
624:
625:
630: public Element createElementNS(String namespaceURI, String name)
631: {
632: if (checkingCharacters)
633: {
634: checkNCName(name, "1.1".equals(version));
635: }
636:
637: if ("".equals(namespaceURI))
638: {
639: namespaceURI = null;
640: }
641: if (name.startsWith("xml:"))
642: {
643: if (namespaceURI != null
644: && !XMLConstants.XML_NS_URI.equals(namespaceURI))
645: {
646: throw new DomDOMException(DOMException.NAMESPACE_ERR,
647: "xml namespace is always " +
648: XMLConstants.XML_NS_URI, this, 0);
649: }
650: namespaceURI = XMLConstants.XML_NS_URI;
651: }
652: else if (XMLConstants.XMLNS_ATTRIBUTE.equals(name) ||
653: name.startsWith("xmlns:"))
654: {
655: throw new DomDOMException(DOMException.NAMESPACE_ERR,
656: "xmlns is reserved", this, 0);
657: }
658: else if (namespaceURI == null && name.indexOf(':') != -1)
659: {
660: throw new DomDOMException(DOMException.NAMESPACE_ERR,
661: "prefixed name '" + name +
662: "' needs a URI", this, 0);
663: }
664:
665: Element element = new DomElement(this, namespaceURI, name);
666: if (defaultAttributes)
667: setDefaultAttributes(element, name);
668: return element;
669: }
670:
671: private void setDefaultAttributes(Element element, String name)
672: {
673: DomDoctype doctype = (DomDoctype) getDoctype();
674: if (doctype == null)
675: {
676: return;
677: }
678:
679:
680: DTDElementTypeInfo info = doctype.getElementTypeInfo(name);
681: if (info != null)
682: {
683: for (Iterator i = info.attributes(); i != null && i.hasNext(); )
684: {
685: DTDAttributeTypeInfo attr = (DTDAttributeTypeInfo) i.next();
686: String value = attr.value;
687: if ("#IMPLIED".equals(attr.mode) && value == null)
688: continue;
689: DomAttr node = (DomAttr) createAttribute(attr.name);
690:
691: if (value == null)
692: {
693: value = "";
694: }
695: node.setValue(value);
696: node.setSpecified(false);
697: element.setAttributeNode(node);
698: }
699: }
700: }
701:
702:
706: public DocumentFragment createDocumentFragment()
707: {
708: return new DomDocumentFragment(this);
709: }
710:
711:
715: public Text createTextNode(String value)
716: {
717: if (checkingCharacters)
718: {
719: checkChar(value, "1.1".equals(version));
720: }
721: return new DomText(this, value);
722: }
723:
724:
727: public Text createTextNode(char[] buf, int off, int len)
728: {
729: if (checkingCharacters)
730: {
731: checkChar(buf, off, len, "1.1".equals(version));
732: }
733: return new DomText(this, buf, off, len);
734: }
735:
736:
740: public Comment createComment(String value)
741: {
742: if (checkingCharacters)
743: {
744: checkChar(value, "1.1".equals(version));
745: }
746: return new DomComment(this, value);
747: }
748:
749:
753: public CDATASection createCDATASection(String value)
754: {
755: if (checkingCharacters)
756: {
757: checkChar(value, "1.1".equals(version));
758: }
759: return new DomCDATASection(this, value);
760: }
761:
762:
765: public CDATASection createCDATASection(char[] buf, int off, int len)
766: {
767: if (checkingCharacters)
768: {
769: checkChar(buf, off, len, "1.1".equals(version));
770: }
771: return new DomCDATASection(this, buf, off, len);
772: }
773:
774:
778: public ProcessingInstruction createProcessingInstruction(String target,
779: String data)
780: {
781: if (checkingCharacters)
782: {
783: boolean xml11 = "1.1".equals(version);
784: checkName(target, xml11);
785: if ("xml".equalsIgnoreCase(target))
786: {
787: throw new DomDOMException(DOMException.SYNTAX_ERR,
788: "illegal PI target name",
789: this, 0);
790: }
791: checkChar(data, xml11);
792: }
793: return new DomProcessingInstruction(this, target, data);
794: }
795:
796:
800: public Attr createAttribute(String name)
801: {
802: if (checkingCharacters)
803: {
804: checkName(name, "1.1".equals(version));
805: }
806: if (name.startsWith("xml:"))
807: {
808: return createAttributeNS(XMLConstants.XML_NS_URI, name);
809: }
810: else if (XMLConstants.XMLNS_ATTRIBUTE.equals(name) ||
811: name.startsWith("xmlns:"))
812: {
813: return createAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, name);
814: }
815: else
816: {
817: DomAttr ret = new DomAttr(this, null, name, null, null);
818: return ret;
819: }
820: }
821:
822:
827: public Attr createAttributeNS(String namespaceURI, String name)
828: {
829: if (checkingCharacters)
830: {
831: checkNCName(name, "1.1".equals(version));
832: }
833:
834: if ("".equals(namespaceURI))
835: {
836: namespaceURI = null;
837: }
838: if (name.startsWith ("xml:"))
839: {
840: if (namespaceURI == null)
841: {
842: namespaceURI = XMLConstants.XML_NS_URI;
843: }
844: else if (!XMLConstants.XML_NS_URI.equals(namespaceURI))
845: {
846: throw new DomDOMException(DOMException.NAMESPACE_ERR,
847: "xml namespace is always " +
848: XMLConstants.XML_NS_URI,
849: this, 0);
850: }
851: }
852: else if (XMLConstants.XMLNS_ATTRIBUTE.equals(name) ||
853: name.startsWith("xmlns:"))
854: {
855: if (namespaceURI == null)
856: {
857: namespaceURI = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
858: }
859: else if (!XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI))
860: {
861: throw new DomDOMException(DOMException.NAMESPACE_ERR,
862: "xmlns namespace must be " +
863: XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
864: this, 0);
865: }
866: }
867: else if (namespaceURI == null && name.indexOf(':') != -1)
868: {
869: throw new DomDOMException(DOMException.NAMESPACE_ERR,
870: "prefixed name needs a URI: " + name, this, 0);
871: }
872: return new DomAttr(this, namespaceURI, name);
873: }
874:
875:
883: public EntityReference createEntityReference(String name)
884: {
885: DomEntityReference ret = new DomEntityReference(this, name);
886: DocumentType doctype = getDoctype();
887: if (doctype != null)
888: {
889: DomEntity ent = (DomEntity) doctype.getEntities().getNamedItem(name);
890: if (ent != null)
891: {
892: for (DomNode ctx = ent.first; ctx != null; ctx = ctx.next)
893: {
894: ret.appendChild(ctx.cloneNode(true));
895: }
896: }
897: }
898: ret.makeReadonly();
899: return ret;
900: }
901:
902:
918: public Node importNode(Node src, boolean deep)
919: {
920: Node dst = null;
921: switch (src.getNodeType())
922: {
923: case TEXT_NODE:
924: dst = createTextNode(src.getNodeValue());
925: break;
926: case CDATA_SECTION_NODE:
927: dst = createCDATASection(src.getNodeValue());
928: break;
929: case COMMENT_NODE:
930: dst = createComment(src.getNodeValue());
931: break;
932: case PROCESSING_INSTRUCTION_NODE:
933: dst = createProcessingInstruction(src.getNodeName(),
934: src.getNodeValue());
935: break;
936: case NOTATION_NODE:
937:
938:
939: Notation notation = (Notation) src;
940: dst = new DomNotation(this, notation.getNodeName(),
941: notation.getPublicId(),
942: notation.getSystemId());
943: break;
944: case ENTITY_NODE:
945:
946:
947: Entity entity = (Entity) src;
948: dst = new DomEntity(this, entity.getNodeName(),
949: entity.getPublicId(),
950: entity.getSystemId(),
951: entity.getNotationName());
952: if (deep)
953: {
954: for (Node ctx = src.getFirstChild(); ctx != null;
955: ctx = ctx.getNextSibling())
956: {
957: dst.appendChild(importNode(ctx, deep));
958: }
959: }
960: break;
961: case ENTITY_REFERENCE_NODE:
962: dst = createEntityReference(src.getNodeName());
963: break;
964: case DOCUMENT_FRAGMENT_NODE:
965: dst = new DomDocumentFragment(this);
966: if (deep)
967: {
968: for (Node ctx = src.getFirstChild(); ctx != null;
969: ctx = ctx.getNextSibling())
970: {
971: dst.appendChild(importNode(ctx, deep));
972: }
973: }
974: break;
975: case ATTRIBUTE_NODE:
976: String attr_nsuri = src.getNamespaceURI();
977: if (attr_nsuri != null)
978: {
979: dst = createAttributeNS(attr_nsuri, src.getNodeName());
980: }
981: else
982: {
983: dst = createAttribute(src.getNodeName());
984: }
985:
986: for (Node ctx = src.getFirstChild(); ctx != null;
987: ctx = ctx.getNextSibling())
988: {
989: dst.appendChild(importNode(ctx, false));
990: }
991: break;
992: case ELEMENT_NODE:
993: String elem_nsuri = src.getNamespaceURI();
994: if (elem_nsuri != null)
995: {
996: dst = createElementNS(elem_nsuri, src.getNodeName());
997: }
998: else
999: {
1000: dst = createElement(src.getNodeName());
1001: }
1002: NamedNodeMap srcAttrs = src.getAttributes();
1003: NamedNodeMap dstAttrs = dst.getAttributes();
1004: int len = srcAttrs.getLength();
1005: for (int i = 0; i < len; i++)
1006: {
1007: Attr a = (Attr) srcAttrs.item(i);
1008: Attr dflt;
1009:
1010:
1011: dflt = (Attr) dstAttrs.getNamedItem(a.getNodeName());
1012: if (dflt != null)
1013: {
1014: String newval = a.getNodeValue();
1015: if (!dflt.getNodeValue().equals(newval)
1016: || a.getSpecified () == true)
1017: {
1018: dflt.setNodeValue (newval);
1019: }
1020: continue;
1021: }
1022:
1023: dstAttrs.setNamedItem((Attr) importNode(a, false));
1024: }
1025: if (deep)
1026: {
1027: for (Node ctx = src.getFirstChild(); ctx != null;
1028: ctx = ctx.getNextSibling())
1029: {
1030: dst.appendChild(importNode(ctx, true));
1031: }
1032: }
1033: break;
1034:
1035: case DOCUMENT_NODE:
1036: case DOCUMENT_TYPE_NODE:
1037:
1038:
1039: default:
1040: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR, null, src, 0);
1041: }
1042:
1043:
1044:
1045:
1046: if (src instanceof DomNode)
1047: {
1048: ((DomNode) src).notifyUserDataHandlers(UserDataHandler.NODE_IMPORTED,
1049: src, dst);
1050: }
1051: return dst;
1052: }
1053:
1054:
1061: public NodeIterator createNodeIterator(Node root,
1062: int whatToShow,
1063: NodeFilter filter,
1064: boolean expandEntities)
1065: {
1066: return new DomNodeIterator(root, whatToShow, filter, expandEntities,
1067: false);
1068: }
1069:
1070: public TreeWalker createTreeWalker(Node root,
1071: int whatToShow,
1072: NodeFilter filter,
1073: boolean expandEntities)
1074: {
1075: return new DomNodeIterator(root, whatToShow, filter, expandEntities,
1076: true);
1077: }
1078:
1079:
1080:
1081:
1084: public String getInputEncoding()
1085: {
1086: return inputEncoding;
1087: }
1088:
1089: public void setInputEncoding(String inputEncoding)
1090: {
1091: this.inputEncoding = inputEncoding;
1092: }
1093:
1094:
1097: public String getXmlEncoding()
1098: {
1099: return encoding;
1100: }
1101:
1102: public void setXmlEncoding(String encoding)
1103: {
1104: this.encoding = encoding;
1105: }
1106:
1107: public boolean getXmlStandalone()
1108: {
1109: return standalone;
1110: }
1111:
1112: public void setXmlStandalone(boolean xmlStandalone)
1113: {
1114: standalone = xmlStandalone;
1115: }
1116:
1117: public String getXmlVersion()
1118: {
1119: return version;
1120: }
1121:
1122: public void setXmlVersion(String xmlVersion)
1123: {
1124: if (xmlVersion == null)
1125: {
1126: xmlVersion = "1.0";
1127: }
1128: if ("1.0".equals(xmlVersion) ||
1129: "1.1".equals(xmlVersion))
1130: {
1131: version = xmlVersion;
1132: }
1133: else
1134: {
1135: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
1136: }
1137: }
1138:
1139: public boolean getStrictErrorChecking()
1140: {
1141: return checkingCharacters;
1142: }
1143:
1144: public void setStrictErrorChecking(boolean strictErrorChecking)
1145: {
1146: checkingCharacters = strictErrorChecking;
1147: }
1148:
1149: public String lookupPrefix(String namespaceURI)
1150: {
1151: Node root = getDocumentElement();
1152: return (root == null) ? null : root.lookupPrefix(namespaceURI);
1153: }
1154:
1155: public boolean isDefaultNamespace(String namespaceURI)
1156: {
1157: Node root = getDocumentElement();
1158: return (root == null) ? false : root.isDefaultNamespace(namespaceURI);
1159: }
1160:
1161: public String lookupNamespaceURI(String prefix)
1162: {
1163: Node root = getDocumentElement();
1164: return (root == null) ? null : root.lookupNamespaceURI(prefix);
1165: }
1166:
1167: public String getBaseURI()
1168: {
1169: return getDocumentURI();
1170:
1183: }
1184:
1185: public String getDocumentURI()
1186: {
1187: return systemId;
1188: }
1189:
1190: public void setDocumentURI(String documentURI)
1191: {
1192: systemId = documentURI;
1193: }
1194:
1195: public Node adoptNode(Node source)
1196: {
1197: int sourceNodeType = source.getNodeType();
1198: switch (sourceNodeType)
1199: {
1200: case DOCUMENT_NODE:
1201: case DOCUMENT_TYPE_NODE:
1202: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
1203: case ENTITY_NODE:
1204: case NOTATION_NODE:
1205: throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
1206: }
1207: if (source instanceof DomNode)
1208: {
1209:
1210: DomNode src = (DomNode) source;
1211: DomNode dst = src;
1212: if (dst.parent != null)
1213: {
1214: dst = (DomNode) dst.cloneNode(true);
1215: }
1216: dst.setOwner(this);
1217: src.notifyUserDataHandlers(UserDataHandler.NODE_ADOPTED, src, dst);
1218: return dst;
1219: }
1220: else
1221: {
1222:
1223: Node dst = null;
1224: switch (sourceNodeType)
1225: {
1226: case Node.ATTRIBUTE_NODE:
1227: {
1228: Attr src = (Attr) source;
1229: String nodeName = src.getNodeName();
1230: String localName = src.getLocalName();
1231: String namespaceUri = src.getNamespaceURI();
1232: dst = (localName == null) ?
1233: createAttribute(nodeName) :
1234: createAttributeNS(namespaceUri, nodeName);
1235: adoptChildren(src, dst);
1236: break;
1237: }
1238: case Node.CDATA_SECTION_NODE:
1239: {
1240: CDATASection src = (CDATASection) source;
1241: dst = createCDATASection(src.getData());
1242: break;
1243: }
1244: case Node.COMMENT_NODE:
1245: {
1246: Comment src = (Comment) source;
1247: dst = createComment(src.getData());
1248: break;
1249: }
1250: case Node.DOCUMENT_FRAGMENT_NODE:
1251: {
1252: DocumentFragment src = (DocumentFragment) source;
1253: dst = createDocumentFragment();
1254: adoptChildren(src, dst);
1255: break;
1256: }
1257: case Node.ELEMENT_NODE:
1258: {
1259: Element src = (Element) source;
1260: String nodeName = src.getNodeName();
1261: String localName = src.getLocalName();
1262: String namespaceUri = src.getNamespaceURI();
1263: dst = (localName == null) ?
1264: createElement(nodeName) :
1265: createElementNS(namespaceUri, nodeName);
1266: adoptAttributes(src, dst);
1267: adoptChildren(src, dst);
1268: break;
1269: }
1270: case Node.ENTITY_REFERENCE_NODE:
1271: {
1272: EntityReference src = (EntityReference) source;
1273: dst = createEntityReference(src.getNodeName());
1274: adoptChildren(src, dst);
1275: break;
1276: }
1277: case Node.PROCESSING_INSTRUCTION_NODE:
1278: {
1279: ProcessingInstruction src = (ProcessingInstruction) source;
1280: dst = createProcessingInstruction(src.getTarget(),
1281: src.getData());
1282: break;
1283: }
1284: case Node.TEXT_NODE:
1285: {
1286: Text src = (Text) source;
1287: dst = createTextNode(src.getData());
1288: break;
1289: }
1290: }
1291: return dst;
1292: }
1293: }
1294:
1295: void adoptChildren(Node src, Node dst)
1296: {
1297: Node node = src.getFirstChild();
1298: while (node != null)
1299: {
1300: Node next = node.getNextSibling();
1301: dst.appendChild(adoptNode(node));
1302: node = next;
1303: }
1304: }
1305:
1306: void adoptAttributes(Node src, Node dst)
1307: {
1308: NamedNodeMap srcAttrs = src.getAttributes();
1309: NamedNodeMap dstAttrs = dst.getAttributes();
1310: int len = srcAttrs.getLength();
1311: for (int i = 0; i < len; i++)
1312: {
1313: Node node = srcAttrs.item(i);
1314: String localName = node.getLocalName();
1315: if (localName == null)
1316: {
1317: dstAttrs.setNamedItem(adoptNode(node));
1318: }
1319: else
1320: {
1321: dstAttrs.setNamedItemNS(adoptNode(node));
1322: }
1323: }
1324: }
1325:
1326: public DOMConfiguration getDomConfig()
1327: {
1328: if (config == null)
1329: {
1330: config = new DomDocumentConfiguration();
1331: }
1332: return config;
1333: }
1334:
1335: public boolean isEqualNode(Node arg)
1336: {
1337: if (!super.isEqualNode(arg))
1338: return false;
1339: Document d = (Document) arg;
1340: String dversion = d.getXmlVersion();
1341: if (dversion == null || !dversion.equals(version))
1342: return false;
1343: boolean dstandalone = d.getXmlStandalone();
1344: if (dstandalone != standalone)
1345: return false;
1346: String dencoding = d.getXmlEncoding();
1347: if (dencoding == null || dencoding.equalsIgnoreCase("UTF-8"))
1348: {
1349: if (encoding != null && !encoding.equalsIgnoreCase("UTF-8"))
1350: return false;
1351: }
1352: else
1353: {
1354: if (!dencoding.equals(encoding))
1355: return false;
1356: }
1357: return true;
1358: }
1359:
1360: public void normalizeDocument()
1361: {
1362: boolean save = building;
1363: building = true;
1364: normalizeNode(this);
1365: building = save;
1366: }
1367:
1368: void normalizeNode(DomNode node)
1369: {
1370: node.normalize();
1371: if (config != null)
1372: {
1373: switch (node.nodeType)
1374: {
1375: case CDATA_SECTION_NODE:
1376: if (!config.cdataSections)
1377: {
1378:
1379: Text text = createTextNode(node.getNodeValue());
1380: node.parent.insertBefore(text, node);
1381: node.parent.removeChild(node);
1382:
1383: String data = text.getWholeText();
1384: node = (DomNode) text.replaceWholeText(data);
1385: }
1386: else if (config.splitCdataSections)
1387: {
1388: String value = node.getNodeValue();
1389: int i = value.indexOf("]]>");
1390: while (i != -1)
1391: {
1392: Node node2 = createCDATASection(value.substring(0, i));
1393: node.parent.insertBefore(node2, node);
1394: value = value.substring(i + 3);
1395: node.setNodeValue(value);
1396: i = value.indexOf("]]>");
1397: }
1398: }
1399: break;
1400: case COMMENT_NODE:
1401: if (!config.comments)
1402: {
1403: node.parent.removeChild(node);
1404: }
1405: break;
1406: case TEXT_NODE:
1407: if (!config.elementContentWhitespace &&
1408: ((Text) node).isElementContentWhitespace())
1409: {
1410: node.parent.removeChild(node);
1411: }
1412: break;
1413: case ENTITY_REFERENCE_NODE:
1414: if (!config.entities)
1415: {
1416: for (DomNode ctx = node.first; ctx != null; )
1417: {
1418: DomNode ctxNext = ctx.next;
1419: node.parent.insertBefore(ctx, node);
1420: ctx = ctxNext;
1421: }
1422: node.parent.removeChild(node);
1423: }
1424: break;
1425: case ELEMENT_NODE:
1426: if (!config.namespaceDeclarations)
1427: {
1428: DomNamedNodeMap attrs =
1429: (DomNamedNodeMap) node.getAttributes();
1430: boolean aro = attrs.readonly;
1431: attrs.readonly = false;
1432: int len = attrs.getLength();
1433: for (int i = 0; i < len; i++)
1434: {
1435: Node attr = attrs.item(i);
1436: String namespace = attr.getNamespaceURI();
1437: if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespace))
1438: {
1439: attrs.removeNamedItemNS(namespace,
1440: attr.getLocalName());
1441: i--;
1442: len--;
1443: }
1444: }
1445: attrs.readonly = aro;
1446: }
1447: break;
1448: }
1449: }
1450: for (DomNode ctx = node.first; ctx != null; )
1451: {
1452: DomNode ctxNext = ctx.next;
1453: normalizeNode(ctx);
1454: ctx = ctxNext;
1455: }
1456: }
1457:
1458: public Node renameNode(Node n, String namespaceURI, String qualifiedName)
1459: throws DOMException
1460: {
1461: if (n instanceof DomNsNode)
1462: {
1463: DomNsNode src = (DomNsNode) n;
1464: if (src == null)
1465: {
1466: throw new DomDOMException(DOMException.NOT_FOUND_ERR);
1467: }
1468: if (src.owner != this)
1469: {
1470: throw new DomDOMException(DOMException.WRONG_DOCUMENT_ERR,
1471: null, src, 0);
1472: }
1473: boolean xml11 = "1.1".equals(version);
1474: checkName(qualifiedName, xml11);
1475: int ci = qualifiedName.indexOf(':');
1476: if ("".equals(namespaceURI))
1477: {
1478: namespaceURI = null;
1479: }
1480: if (namespaceURI != null)
1481: {
1482: checkNCName(qualifiedName, xml11);
1483: String prefix = (ci == -1) ? "" :
1484: qualifiedName.substring(0, ci);
1485: if (XMLConstants.XML_NS_PREFIX.equals(prefix) &&
1486: !XMLConstants.XML_NS_URI.equals(namespaceURI))
1487: {
1488: throw new DomDOMException(DOMException.NAMESPACE_ERR,
1489: "xml namespace must be " +
1490: XMLConstants.XML_NS_URI, src, 0);
1491: }
1492: else if (src.nodeType == ATTRIBUTE_NODE &&
1493: (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix) ||
1494: XMLConstants.XMLNS_ATTRIBUTE.equals(qualifiedName)) &&
1495: !XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI))
1496: {
1497: throw new DomDOMException(DOMException.NAMESPACE_ERR,
1498: "xmlns namespace must be " +
1499: XMLConstants.XMLNS_ATTRIBUTE_NS_URI, src, 0);
1500: }
1501: if (XMLConstants.XML_NS_URI.equals(namespaceURI) &&
1502: !XMLConstants.XML_NS_PREFIX.equals(prefix))
1503: {
1504: throw new DomDOMException(DOMException.NAMESPACE_ERR,
1505: "xml namespace must be " +
1506: XMLConstants.XML_NS_URI, src, 0);
1507: }
1508: else if (src.nodeType == ATTRIBUTE_NODE &&
1509: XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI) &&
1510: !(XMLConstants.XMLNS_ATTRIBUTE.equals(prefix) ||
1511: XMLConstants.XMLNS_ATTRIBUTE.equals(qualifiedName)))
1512: {
1513: throw new DomDOMException(DOMException.NAMESPACE_ERR,
1514: "xmlns namespace must be " +
1515: XMLConstants.XMLNS_ATTRIBUTE_NS_URI, src, 0);
1516: }
1517:
1518: }
1519: src.setNodeName(qualifiedName);
1520: src.setNamespaceURI(namespaceURI);
1521: src.notifyUserDataHandlers(UserDataHandler.NODE_RENAMED, src, src);
1522:
1523:
1524: return src;
1525: }
1526: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR, null, n, 0);
1527: }
1528:
1529:
1530:
1531: public XPathExpression createExpression(String expression,
1532: XPathNSResolver resolver)
1533: throws XPathException, DOMException
1534: {
1535: return new DomXPathExpression(this, expression, resolver);
1536: }
1537:
1538: public XPathNSResolver createNSResolver(Node nodeResolver)
1539: {
1540: return new DomXPathNSResolver(nodeResolver);
1541: }
1542:
1543: public Object evaluate(String expression,
1544: Node contextNode,
1545: XPathNSResolver resolver,
1546: short type,
1547: Object result)
1548: throws XPathException, DOMException
1549: {
1550: XPathExpression xpe =
1551: new DomXPathExpression(this, expression, resolver);
1552: return xpe.evaluate(contextNode, type, result);
1553: }
1554:
1555: }