1 /**
2 * Phoebe DOM Implementation.
3 *
4 * This is a C++ approximation of the W3C DOM model, which follows
5 * fairly closely the specifications in the various .idl files, copies of
6 * which are provided for reference. Most important is this one:
7 *
8 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
9 *
10 * Authors:
11 * Bob Jamison
12 *
13 * Copyright (C) 2005-2008 Bob Jamison
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
31 #include "domimpl.h"
33 namespace org
34 {
35 namespace w3c
36 {
37 namespace dom
38 {
41 /**
42 * Test if the given substring exists for the length of the string
43 * in a given buffer
44 */
45 /*
46 static bool match(const DOMString &buf, char *str)
47 {
48 int pos = 0;
49 while (*str)
50 {
51 if (buf[pos++] != *str++)
52 return false;
53 }
54 return true;
55 }
56 */
60 /*#########################################################################
61 ## DOMImplementationSourceImpl
62 #########################################################################*/
65 /**
66 *
67 */
68 DOMImplementationSourceImpl::DOMImplementationSourceImpl()
69 {
70 domImpl = new DOMImplementationImpl();
71 }
73 /**
74 *
75 */
76 DOMImplementationSourceImpl::~DOMImplementationSourceImpl()
77 {
78 delete domImpl;
79 }
81 /**
82 *
83 */
84 DOMImplementation *DOMImplementationSourceImpl::getDOMImplementation(
85 const DOMString &/*features*/)
86 {
87 return domImpl;
88 }
90 /**
91 *
92 */
93 DOMImplementationList DOMImplementationSourceImpl::getDOMImplementationList(
94 const DOMString &/*features*/)
95 {
96 return domImplList;
97 }
105 /*#########################################################################
106 ## DOMImplementationImpl
107 #########################################################################*/
110 /**
111 *
112 */
113 DOMImplementationImpl::DOMImplementationImpl()
114 {
115 }
117 /**
118 *
119 */
120 DOMImplementationImpl::~DOMImplementationImpl()
121 {
122 }
124 /**
125 *
126 */
127 bool DOMImplementationImpl::hasFeature(const DOMString& /*feature*/,
128 const DOMString& /*version*/)
129 {
130 return false;
131 }
134 /**
135 *
136 */
137 DocumentTypePtr DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName,
138 const DOMString& publicId,
139 const DOMString& systemId)
140 throw(DOMException)
141 {
142 DocumentTypePtr typeImpl = new DocumentTypeImpl(qualifiedName,
143 publicId, systemId);
144 return typeImpl;
145 }
147 /**
148 *
149 */
150 DocumentPtr DOMImplementationImpl::createDocument(
151 const DOMString& namespaceURI,
152 const DOMString& qualifiedName,
153 DocumentTypePtr doctype)
154 throw(DOMException)
155 {
156 DocumentPtr doc = new DocumentImpl(this,
157 namespaceURI,
158 qualifiedName,
159 doctype);
160 return doc;
161 }
163 /**
164 *
165 */
166 DOMObject *DOMImplementationImpl::getFeature(const DOMString& /*feature*/,
167 const DOMString& /*version*/)
169 {
170 return NULL;
171 }
177 /*#########################################################################
178 ## NodeImpl
179 #########################################################################*/
181 /**
182 * Utility for finding the first Element above
183 * a given node. Used by several methods below
184 */
185 static NodePtr getAncestorElement(NodePtr node)
186 {
187 if (!node.get())
188 return NULL;
189 node = node->getParentNode();
190 //Either quit because I am an element, or because I am null
191 while (node.get())
192 {
193 if (node->getNodeType() == Node::ELEMENT_NODE)
194 return node;
195 node = node->getParentNode();
196 }
197 return node;
198 }
200 /**
201 *
202 */
203 DOMString NodeImpl::getNodeName()
204 {
205 return nodeName;
206 }
208 /**
209 *
210 */
211 DOMString NodeImpl::getNodeValue() throw (DOMException)
212 {
213 return nodeValue;
214 }
216 /**
217 *
218 */
219 void NodeImpl::setNodeValue(const DOMString& val) throw (DOMException)
220 {
221 nodeValue = val;
222 }
224 /**
225 *
226 */
227 unsigned short NodeImpl::getNodeType()
228 {
229 return nodeType;
230 }
232 /**
233 *
234 */
235 NodePtr NodeImpl::getParentNode()
236 {
237 return parent;
238 }
240 /**
241 *
242 */
243 NodeList NodeImpl::getChildNodes()
244 {
245 NodeList list;
246 for (NodeImplPtr node = firstChild ; node.get() ; node=node->next)
247 list.add(node);
248 return list;
249 }
251 /**
252 *
253 */
254 NodePtr NodeImpl::getFirstChild()
255 {
256 return firstChild;
257 }
259 /**
260 *
261 */
262 NodePtr NodeImpl::getLastChild()
263 {
264 return lastChild;
265 }
267 /**
268 *
269 */
270 NodePtr NodeImpl::getPreviousSibling()
271 {
272 return prev;
273 }
275 /**
276 *
277 */
278 NodePtr NodeImpl::getNextSibling()
279 {
280 return next;
281 }
283 /**
284 *
285 */
286 NamedNodeMap &NodeImpl::getAttributes()
287 {
288 NamedNodeMap &attrs = attributes;
289 return attrs;
290 }
293 /**
294 *
295 */
296 DocumentPtr NodeImpl::getOwnerDocument()
297 {
298 return ownerDocument;
299 }
301 /**
302 *
303 */
304 NodePtr NodeImpl::insertBefore(const NodePtr newChild,
305 const NodePtr refChild)
306 throw(DOMException)
307 {
308 if (!newChild)
309 return NULL;
311 //if no ref, then just append
312 if (!refChild)
313 return appendChild(newChild);
315 NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
316 for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
317 {
318 if (n == refChild)
319 {
320 //link to new
321 if (n->prev.get())
322 n->prev->next = newChildImpl;
323 else
324 firstChild = newChildImpl;
325 n->prev = newChildImpl;
326 //link from new
327 newChildImpl->next = n;
328 newChildImpl->prev = n->prev;
329 //reflect new location
330 newChildImpl->parent = this;
331 newChildImpl->ownerDocument = ownerDocument;
332 return n;
333 }
334 }
335 return NULL;
336 }
338 /**
339 *
340 */
341 NodePtr NodeImpl::replaceChild(const NodePtr newChild,
342 const NodePtr oldChild)
343 throw(DOMException)
344 {
345 if (!oldChild)
346 return NULL;
348 NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
349 for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
350 {
351 if (n == oldChild)
352 {
353 //link to new
354 if (n->prev.get())
355 n->prev->next = newChildImpl;
356 else
357 firstChild = newChildImpl;
358 if (n->next.get())
359 n->next->prev = newChildImpl;
360 else
361 lastChild = newChildImpl;
362 //link from new
363 newChildImpl->next = n->next;
364 newChildImpl->prev = n->prev;
365 //reflect new location
366 newChildImpl->parent = this;
367 newChildImpl->ownerDocument = ownerDocument;
368 return n;
369 }
370 }
371 return NULL;
372 }
374 /**
375 *
376 */
377 NodePtr NodeImpl::removeChild(const NodePtr oldChild)
378 throw(DOMException)
379 {
380 if (!oldChild)
381 return NULL;
383 for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
384 {
385 if (n == oldChild)
386 {
387 if (n->prev.get())
388 n->prev->next = n->next;
389 if (n->next.get())
390 n->next->prev = n->prev;
391 return n;
392 }
393 }
394 return NULL;
395 }
397 /**
398 *
399 */
400 NodePtr NodeImpl::appendChild(const NodePtr newChild)
401 throw(DOMException)
402 {
403 if (!newChild)
404 return NULL;
406 NodeImplPtr newChildImpl =
407 dynamic_cast<NodeImpl *> (newChild.get());
409 newChildImpl->parent = this;
410 newChildImpl->ownerDocument = ownerDocument;
412 if (!firstChild || !lastChild)
413 {
414 //Set up our first member
415 firstChild = newChildImpl;
416 lastChild = newChildImpl;
417 }
418 else
419 {
420 //link at the last position
421 lastChild->next = newChildImpl;
422 newChildImpl->prev = lastChild;
423 lastChild = newChildImpl;
424 }
426 return newChild;
427 }
429 /**
430 *
431 */
432 bool NodeImpl::hasChildNodes()
433 {
434 return (firstChild != (NodeImpl *)0);
435 }
437 /**
438 *
439 */
440 NodePtr NodeImpl::cloneNode(bool deep)
441 {
442 NodeImplPtr node = new NodeImpl(ownerDocument, nodeName);
443 node->parent = parent;
444 node->prev = prev;
445 node->next = next;
446 node->userData = userData;
447 node->nodeValue = nodeValue;
449 if (deep)
450 {
451 node->firstChild = node->lastChild = NULL;
452 for (NodeImplPtr child = firstChild ; child.get() ; child=child->next)
453 {
454 node->appendChild(child->cloneNode(deep));
455 }
456 }
457 else
458 {
459 node->firstChild = firstChild;
460 node->lastChild = lastChild;
461 }
463 return node;
464 }
466 /**
467 * Concatenate adjoining text subnodes, remove null-length nodes
468 */
469 void NodeImpl::normalize()
470 {
471 //First, concatenate adjoining text nodes
472 NodeImplPtr next = (NodeImpl *)0;
473 for (NodeImplPtr child = firstChild ; child.get() ; child=next)
474 {
475 if (child->getNodeType() != Node::TEXT_NODE)
476 continue;
477 next = NULL;
478 DOMString sval = child->getNodeValue();
479 for (NodeImplPtr sibling = child->next ; sibling.get() ; sibling=next)
480 {
481 next = sibling->next;
482 if (sibling->getNodeType() != Node::TEXT_NODE)
483 break;
484 sval.append(sibling->getNodeValue());
485 //unlink and delete
486 child->next = sibling->next;
487 if (sibling->next.get())
488 sibling->next->prev = child;
489 //delete sibling;
490 }
491 child->setNodeValue(sval);
492 }
494 //Next, we remove zero-length text subnodes
495 next = NULL;
496 for (NodeImplPtr child = firstChild ; child.get() ; child=next)
497 {
498 next = child->next;
499 if (child->getNodeType() != Node::TEXT_NODE)
500 continue;
501 if (child->getNodeValue().size() == 0)
502 {
503 //unlink and delete
504 if (child->prev.get())
505 child->prev->next = child->next;
506 if (child->next.get())
507 child->next->prev = child->prev;
508 //delete child;
509 }
510 }
512 }
514 /**
515 *
516 */
517 bool NodeImpl::isSupported(const DOMString& /*feature*/,
518 const DOMString& /*version*/)
519 {
520 //again, no idea
521 return false;
522 }
524 /**
525 *
526 */
527 DOMString NodeImpl::getNamespaceURI()
528 {
529 return namespaceURI;
530 }
532 /**
533 *
534 */
535 DOMString NodeImpl::getPrefix()
536 {
537 return prefix;
538 }
540 /**
541 *
542 */
543 void NodeImpl::setPrefix(const DOMString& val) throw(DOMException)
544 {
545 prefix = val;
546 if (prefix.size()>0)
547 nodeName = prefix + ":" + localName;
548 else
549 nodeName = localName;
550 }
552 /**
553 *
554 */
555 DOMString NodeImpl::getLocalName()
556 {
557 return localName;
558 }
560 /**
561 *
562 */
563 bool NodeImpl::hasAttributes()
564 {
565 return (attributes.getLength() > 0);
566 }
568 /**
569 *
570 */
571 DOMString NodeImpl::getBaseURI()
572 {
573 return baseURI;
574 }
576 /**
577 *
578 */
579 unsigned short NodeImpl::compareDocumentPosition(const NodePtr otherArg)
580 {
581 if (!otherArg || otherArg == (NodePtr )this)
582 return 0;//no flags
584 NodePtr node;
585 NodePtr other = otherArg;
587 //Look above me
588 for (node=getParentNode() ; node.get() ; node=node->getParentNode())
589 if (node == other)
590 return DOCUMENT_POSITION_CONTAINED_BY;
592 //Look above the other guy. See me?
593 for (node=other->getParentNode() ; node.get() ; node=node->getParentNode())
594 if (node == (NodePtr )this)
595 return DOCUMENT_POSITION_CONTAINS;
598 return DOCUMENT_POSITION_DISCONNECTED |
599 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
600 }
602 /**
603 *
604 */
605 DOMString NodeImpl::getTextContent() throw(DOMException)
606 {
607 DOMString buf;
608 if (nodeType == TEXT_NODE ||
609 nodeType == CDATA_SECTION_NODE ||
610 nodeType == COMMENT_NODE ||
611 nodeType == PROCESSING_INSTRUCTION_NODE)
612 buf = getNodeValue();
613 else if (nodeType == ELEMENT_NODE ||
614 nodeType == ATTRIBUTE_NODE ||
615 nodeType == ENTITY_NODE ||
616 nodeType == ENTITY_REFERENCE_NODE ||
617 nodeType == DOCUMENT_FRAGMENT_NODE)
618 {
619 for (NodePtr n = getFirstChild() ; n.get() ;
620 n=n->getNextSibling() )
621 {
622 if (n->getNodeType() != COMMENT_NODE &&
623 n->getNodeType() != COMMENT_NODE)
624 buf.append(n->getTextContent());
625 }
626 }
627 return buf;
628 }
631 /**
632 *
633 */
634 void NodeImpl::setTextContent(const DOMString &val) throw(DOMException)
635 {
636 //Delete children
637 /** Not necessary. Just let smart pointers to their work
638 for (NodePtr n = getFirstChild() ; n.get() ;
639 n=n->getNextSibling() )
640 delete n;
641 */
642 firstChild = lastChild = NULL;
644 //Replace with a single text node
645 NodeImplPtr tnode = new NodeImpl(ownerDocument);
646 tnode->nodeType = Node::TEXT_NODE;
647 tnode->setNodeValue(val);
648 appendChild(tnode);
649 }
652 /**
653 * From DOM3 Namespace algorithms
654 */
655 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
656 {
658 if (theNamespaceURI.size()==0)
659 {
660 return DOMString("");
661 }
663 switch (nodeType)
664 {
665 case Node::ELEMENT_NODE:
666 {
667 ElementPtr elem = (Element *)this;
668 return lookupNamespacePrefix(theNamespaceURI, elem);
669 }
670 case Node::DOCUMENT_NODE:
671 {
672 DocumentPtr doc = (Document *)this;
673 ElementPtr elem = doc->getDocumentElement();
674 return elem->lookupPrefix(theNamespaceURI);
675 }
676 case Node::ENTITY_NODE :
677 case Node::NOTATION_NODE:
678 case Node::DOCUMENT_FRAGMENT_NODE:
679 case Node::DOCUMENT_TYPE_NODE:
680 return DOMString(""); // type is unknown
681 case Node::ATTRIBUTE_NODE:
682 {
683 AttrPtr attr = (Attr *)this;
684 ElementPtr elem = attr->getOwnerElement();
685 if ( elem.get() )
686 {
687 return elem->lookupPrefix(theNamespaceURI);
688 }
689 return DOMString("");
690 }
691 default:
692 {
693 //Get ancestor element, if any
694 NodePtr ancestor = getAncestorElement(this);
695 if ( ancestor.get() )
696 {
697 return ancestor->lookupPrefix(theNamespaceURI);
698 }
699 return DOMString("");
700 }
701 }//switch
702 return DOMString("");
703 }
706 /**
707 *
708 */
709 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
710 {
711 switch (nodeType)
712 {
713 case ELEMENT_NODE:
714 {
715 if ( namespaceURI.size()>0 && prefix.size()==0 )
716 {
717 return (namespaceURI == theNamespaceURI);
718 }
719 NodePtr attr = attributes.getNamedItem("xmlns");
720 if ( attr.get() )
721 {
722 return (attr->getNodeValue() == theNamespaceURI);
723 }
725 NodePtr ancestor = getAncestorElement(this);
726 if ( ancestor.get() )
727 {
728 return ancestor->isDefaultNamespace(theNamespaceURI);
729 }
730 else
731 {
732 return false;
733 }
734 }
735 case DOCUMENT_NODE:
736 { //just use braces for local declaration
737 DocumentPtr doc = (Document *)this;
738 ElementPtr elem = doc->getDocumentElement();
739 return elem->isDefaultNamespace(theNamespaceURI);
740 }
741 case ENTITY_NODE:
742 case NOTATION_NODE:
743 case DOCUMENT_TYPE_NODE:
744 case DOCUMENT_FRAGMENT_NODE:
745 return false;
746 case ATTRIBUTE_NODE:
747 {//braces only for scope
748 AttrPtr attr = (Attr *)this;
749 ElementPtr ownerElement = attr->getOwnerElement();
750 if ( ownerElement.get() )
751 {
752 return ownerElement->isDefaultNamespace(theNamespaceURI);
753 }
754 else
755 {
756 return false;
757 }
758 }
759 default:
760 {
761 NodePtr ancestor = getAncestorElement(this);
762 if ( ancestor.get() )
763 {
764 return ancestor->isDefaultNamespace(theNamespaceURI);
765 }
766 else
767 {
768 return false;
769 }
770 }
771 }//switch
773 return false;
774 }
777 /**
778 *
779 */
780 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
781 {
782 switch (nodeType)
783 {
784 case ELEMENT_NODE:
785 {
786 if ( namespaceURI.size()>0 && prefix == thePrefix )
787 {
788 DOMString nsURI = namespaceURI;
789 return (nsURI);
790 }
791 if ( hasAttributes() )
792 {
793 NamedNodeMap attributes = getAttributes();
794 int nrAttrs = attributes.getLength();
795 for (int i=0 ; i<nrAttrs ; i++)
796 {
797 NodePtr attr = attributes.item(i);
798 if (attr->getPrefix() == "xmlns" && attr->getLocalName() == thePrefix )
799 { // non default namespace
800 if (attr->getNodeValue().size()>0)
801 {
802 return (attr->getNodeValue());
803 }
804 return DOMString("");
805 }
806 else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0)
807 { // default namespace
808 if (attr->getNodeValue().size()>0)
809 {
810 return (attr->getNodeValue());
811 }
812 return DOMString("");
813 }
814 }
815 }
817 NodePtr ancestor = getAncestorElement(this);
818 if ( ancestor.get() )
819 {
820 return ancestor->lookupNamespaceURI(thePrefix);
821 }
822 return DOMString("");
823 }
824 case DOCUMENT_NODE:
825 {
826 DocumentPtr doc = (Document *)this;
827 ElementPtr elem = doc->getDocumentElement();
828 return elem->lookupNamespaceURI(thePrefix);
829 }
830 case ENTITY_NODE:
831 case NOTATION_NODE:
832 case DOCUMENT_TYPE_NODE:
833 case DOCUMENT_FRAGMENT_NODE:
834 return DOMString("");
836 case ATTRIBUTE_NODE:
837 {
838 ElementPtr ownerElement = ((Attr *)this)->getOwnerElement();
839 if ( ownerElement.get() )
840 {
841 return ownerElement->lookupNamespaceURI(thePrefix);
842 }
843 else
844 {
845 return DOMString("");
846 }
847 }
848 default:
849 {
850 NodePtr ancestor = getAncestorElement(this);
851 if ( ancestor.get() )
852 {
853 return ancestor->lookupNamespaceURI(thePrefix);
854 }
855 else
856 {
857 return DOMString("");
858 }
859 }
860 }//switch
861 }
864 /**
865 *
866 */
867 bool NodeImpl::isEqualNode(const NodePtr nodeArg)
868 {
869 if (!nodeArg)
870 return false;
872 if (nodeArg == (NodePtr )this)
873 return true;
875 NodePtr node = nodeArg;
877 if (getNodeType() != node->getNodeType() ||
878 getNodeName() != node->getNodeName() ||
879 getLocalName() != node->getLocalName() ||
880 getNamespaceURI() != node->getNamespaceURI() ||
881 getPrefix() != node->getPrefix() ||
882 getNodeValue() != node->getNodeValue() ||
883 getBaseURI() != node->getBaseURI() )
884 return false;
886 return true;
887 }
891 /**
892 *
893 */
894 DOMObject *NodeImpl::getFeature(const DOMString &/*feature*/,
895 const DOMString &/*version*/)
896 {
897 //dont know
898 return NULL;
899 }
901 /**
902 *
903 */
904 DOMUserData *NodeImpl::setUserData(const DOMString &key,
905 const DOMUserData *data,
906 const UserDataHandler *handler)
907 {
908 UserDataEntry *entry = userDataEntries;
909 UserDataEntry *prev = NULL;
910 while (entry)
911 {
912 if (entry->key == key)
913 {
914 DOMUserData *oldData = entry->data;
915 entry->data = (DOMUserData *)data;
916 entry->handler = (UserDataHandler *)handler;
917 return oldData;
918 }
919 prev = entry;
920 entry = entry->next;
921 }
923 //Make a new one
924 UserDataEntry *newEntry = new UserDataEntry(key, data, handler);
925 if (!prev)
926 userDataEntries = newEntry;
927 else
928 prev->next = newEntry;
930 return NULL;
931 }
933 /**
934 *
935 */
936 DOMUserData *NodeImpl::getUserData(const DOMString &key)
937 {
938 UserDataEntry *entry = userDataEntries;
939 while (entry)
940 {
941 if (entry->key == key)
942 return entry->data;
943 entry = entry->next;
944 }
945 return NULL;
946 }
950 //##################
951 //# Non-API methods
952 //##################
954 /**
955 *
956 */
957 void NodeImpl::setNodeName(const DOMString &qualifiedName)
958 {
959 nodeName = qualifiedName;
960 prefix = "";
961 localName = "";
962 for (unsigned int i=0 ; i<qualifiedName.size() ; i++)
963 {
964 int ch = qualifiedName[i];
965 if (ch == ':')
966 {
967 prefix = localName;
968 localName = "";
969 }
970 else
971 {
972 localName.push_back((XMLCh)ch);
973 }
974 }
975 }
977 /**
978 *
979 */
980 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
981 {
982 namespaceURI = theNamespaceURI;
983 }
986 /**
987 * From DOM3 Namespace algorithms
988 */
989 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
990 NodePtr originalElement)
991 {
992 if (!originalElement)
993 return DOMString("");
995 if ( namespaceURI.size()>0 && namespaceURI==theNamespaceURI &&
996 prefix.size()>0 &&
997 originalElement->lookupNamespaceURI(prefix) == theNamespaceURI)
998 {
999 return (prefix);
1000 }
1002 if ( hasAttributes() )
1003 {
1004 NamedNodeMap attributes = getAttributes();
1005 int nrAttrs = attributes.getLength();
1006 for (int i=0 ; i<nrAttrs ; i++)
1007 {
1008 NodePtr attr = attributes.item(i);
1009 DOMString attrLocalName = attr->getLocalName();
1010 if (attr->getPrefix() == "xmlns" &&
1011 attr->getNodeValue() == theNamespaceURI &&
1012 originalElement->lookupNamespaceURI(attrLocalName)
1013 == theNamespaceURI)
1014 {
1015 return (attrLocalName);
1016 }
1017 }
1018 }
1020 //Get ancestor element, if any
1021 NodeImplPtr ancestor = parent;
1022 while (ancestor.get() && ancestor->getNodeType()!= Node::ELEMENT_NODE)
1023 ancestor = ancestor->parent;
1025 if ( ancestor.get() )
1026 {
1027 return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement);
1028 }
1030 return DOMString("");
1031 }
1034 /**
1035 *
1036 */
1037 NodeImpl::NodeImpl() : Node()
1038 {
1039 init();
1040 }
1043 /**
1044 *
1045 */
1046 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
1047 {
1048 init();
1049 assign(other);
1050 }
1052 /**
1053 *
1054 */
1055 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
1056 {
1057 init();
1058 assign(other);
1059 return *this;
1060 }
1063 /**
1064 *
1065 */
1066 NodeImpl::NodeImpl(DocumentImplPtr owner) : Node()
1067 {
1068 init();
1069 ownerDocument = owner;
1070 }
1072 /**
1073 *
1074 */
1075 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &nodeName)
1076 : Node()
1077 {
1078 init();
1079 ownerDocument = owner;
1080 setNodeName(nodeName);
1081 }
1083 /**
1084 *
1085 */
1086 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &/*theNamespaceURI*/,
1087 const DOMString &qualifiedName) : Node()
1088 {
1089 init();
1090 ownerDocument = owner;
1091 //if (owner)
1092 // namespaceURI = owner->stringCache(theNamespaceURI);
1093 setNodeName(qualifiedName);
1094 }
1098 /**
1099 *
1100 */
1101 void NodeImpl::init()
1102 {
1103 nodeType = 0; //none yet
1104 nodeValue = "";
1105 setNodeName("");
1106 namespaceURI = "";
1107 parent = NULL;
1108 prev = NULL;
1109 next = NULL;
1110 userData = NULL;
1111 firstChild = NULL;
1112 lastChild = NULL;
1113 ownerDocument = NULL;
1114 userDataEntries = NULL;
1115 }
1117 /**
1118 *
1119 */
1120 void NodeImpl::assign(const NodeImpl &other)
1121 {
1122 ownerDocument = other.ownerDocument;
1123 prefix = other.prefix;
1124 localName = other.localName;
1125 nodeName = other.nodeName;
1126 nodeValue = other.nodeValue;
1127 namespaceURI = other.namespaceURI;
1128 attributes = other.attributes;
1129 }
1132 /**
1133 *
1134 */
1135 NodeImpl::~NodeImpl()
1136 {
1137 if (userDataEntries)
1138 delete userDataEntries;
1139 //Delete children
1140 /** Use smart pointers. do not delete explicitly
1141 for (NodePtr n = getFirstChild() ; n.get() ;
1142 n=n->getNextSibling() )
1143 delete n;
1144 */
1145 firstChild = lastChild = (NodeImpl *)0;
1146 }
1150 /*#########################################################################
1151 ## CharacterDataImpl
1152 #########################################################################*/
1155 /**
1156 *
1157 */
1158 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1159 {
1160 }
1162 /**
1163 *
1164 */
1165 CharacterDataImpl::CharacterDataImpl(DocumentImplPtr owner,
1166 const DOMString &theValue) : NodeImpl()
1167 {
1168 ownerDocument = owner;
1169 nodeValue = theValue;
1170 }
1172 /**
1173 *
1174 */
1175 CharacterDataImpl::~CharacterDataImpl()
1176 {
1177 }
1179 /**
1180 *
1181 */
1182 DOMString CharacterDataImpl::getData() throw(DOMException)
1183 {
1184 return nodeValue;
1185 }
1187 /**
1188 *
1189 */
1190 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1191 {
1192 nodeValue = val;
1193 }
1195 /**
1196 *
1197 */
1198 unsigned long CharacterDataImpl::getLength()
1199 {
1200 return nodeValue.size();
1201 }
1203 /**
1204 *
1205 */
1206 DOMString CharacterDataImpl::substringData(unsigned long offset,
1207 unsigned long count)
1208 throw(DOMException)
1209 {
1210 return nodeValue.substr(offset, count);
1211 }
1213 /**
1214 *
1215 */
1216 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1217 {
1218 nodeValue += arg;
1219 }
1221 /**
1222 *
1223 */
1224 void CharacterDataImpl::insertData(unsigned long offset,
1225 const DOMString& arg)
1226 throw(DOMException)
1227 {
1228 nodeValue.insert(offset, arg);
1229 }
1231 /**
1232 *
1233 */
1234 void CharacterDataImpl::deleteData(unsigned long offset,
1235 unsigned long count)
1236 throw(DOMException)
1237 {
1238 nodeValue.erase(offset, count);
1239 }
1241 /**
1242 *
1243 */
1244 void CharacterDataImpl::replaceData(unsigned long offset,
1245 unsigned long count,
1246 const DOMString& arg)
1247 throw(DOMException)
1248 {
1249 nodeValue.replace(offset, count, arg);
1250 }
1257 /*#########################################################################
1258 ## AttrImpl
1259 #########################################################################*/
1261 /**
1262 *
1263 */
1264 DOMString AttrImpl::getName()
1265 {
1266 return nodeName;
1267 }
1269 /**
1270 *
1271 */
1272 bool AttrImpl::getSpecified()
1273 {
1274 return (nodeValue.size() > 0);
1275 }
1277 /**
1278 *
1279 */
1280 DOMString AttrImpl::getValue()
1281 {
1282 return nodeValue;
1283 }
1285 /**
1286 *
1287 */
1288 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1289 {
1290 nodeValue = val;
1291 }
1293 /**
1294 *
1295 */
1296 ElementPtr AttrImpl::getOwnerElement()
1297 {
1298 return ownerElement;
1299 }
1302 /**
1303 *
1304 */
1305 TypeInfo &AttrImpl::getSchemaTypeInfo()
1306 {
1307 return typeInfo;
1308 }
1311 /**
1312 *
1313 */
1314 bool AttrImpl::getIsId()
1315 {
1316 return (nodeName == "id");
1317 }
1321 //##################
1322 //# Non-API methods
1323 //##################
1326 void AttrImpl::setOwnerElement(const ElementPtr elem)
1327 {
1328 ownerElement = elem;
1329 }
1331 /**
1332 *
1333 */
1334 AttrImpl::AttrImpl(DocumentImplPtr owner, const DOMString &theName)
1335 : NodeImpl()
1336 {
1337 nodeType = ATTRIBUTE_NODE;
1338 ownerDocument = owner;
1339 setNodeName(theName);
1340 }
1342 /**
1343 *
1344 */
1345 AttrImpl::AttrImpl(DocumentImplPtr owner,
1346 const DOMString &/*theNamespaceURI*/,
1347 const DOMString &theQualifiedName)
1348 : NodeImpl()
1349 {
1350 nodeType = ATTRIBUTE_NODE;
1351 ownerDocument = owner;
1352 //if (owner)
1353 // namespaceURI = owner->stringCache(theNamespaceURI);
1354 setNodeName(theQualifiedName);
1355 }
1357 /**
1358 *
1359 */
1360 AttrImpl::~AttrImpl()
1361 {
1362 }
1368 /*#########################################################################
1369 ## ElementImpl
1370 #########################################################################*/
1373 /**
1374 *
1375 */
1376 DOMString ElementImpl::getTagName()
1377 {
1378 if (prefix.size() > 0)
1379 return prefix + ":" + nodeName;
1380 else
1381 return nodeName;
1382 }
1384 /**
1385 *
1386 */
1387 DOMString ElementImpl::getAttribute(const DOMString& name)
1388 {
1389 NodePtr node = attributes.getNamedItem(name);
1390 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1391 return DOMString("");
1392 AttrPtr attr = dynamic_cast<Attr *>(node.get());
1393 return attr->getValue();
1394 }
1396 /**
1397 *
1398 */
1399 void ElementImpl::setAttribute(const DOMString& name,
1400 const DOMString& value)
1401 throw(DOMException)
1402 {
1403 AttrImplPtr attr = new AttrImpl(ownerDocument, name);
1404 attr->setValue(value);
1405 attr->setOwnerElement(this);
1406 attributes.setNamedItem(attr);
1407 }
1409 /**
1410 *
1411 */
1412 void ElementImpl::removeAttribute(const DOMString& name)
1413 throw(DOMException)
1414 {
1415 attributes.removeNamedItem(name);
1416 }
1418 /**
1419 *
1420 */
1421 AttrPtr ElementImpl::getAttributeNode(const DOMString& name)
1422 {
1423 NodePtr node = attributes.getNamedItem(name);
1424 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1425 return NULL;
1426 AttrPtr attr = dynamic_cast<Attr *>(node.get());
1427 return attr;
1428 }
1430 /**
1431 *
1432 */
1433 AttrPtr ElementImpl::setAttributeNode(AttrPtr attr)
1434 throw(DOMException)
1435 {
1436 attributes.setNamedItem(attr);
1437 return attr;
1438 }
1440 /**
1441 *
1442 */
1443 AttrPtr ElementImpl::removeAttributeNode(AttrPtr attr)
1444 throw(DOMException)
1445 {
1446 attributes.removeNamedItem(attr->getName());
1447 return attr;
1448 }
1451 /**
1452 *
1453 */
1454 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1455 const DOMString& name, ElementPtr elem)
1456 {
1457 if (!elem)
1458 return;
1460 if (name == elem->getTagName())
1461 list.add(elem);
1462 for (NodePtr node = elem->getFirstChild() ; node.get() ;
1463 node=node->getNextSibling())
1464 {
1465 if (node->getNodeType() != Node::ELEMENT_NODE)
1466 continue;
1467 ElementPtr childElem = dynamic_cast<Element *>(node.get());
1468 getElementsByTagNameRecursive(list, name, childElem);
1469 }
1470 }
1473 /**
1474 *
1475 */
1476 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1477 {
1478 NodeList list;
1479 getElementsByTagNameRecursive(list, tagName, this);
1480 return list;
1481 }
1483 /**
1484 *
1485 */
1486 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1487 const DOMString& localName)
1488 {
1489 NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1490 if (!node || node->getNodeType()!=ATTRIBUTE_NODE)
1491 return DOMString("");
1492 AttrPtr attr = dynamic_cast<Attr *>(node.get());
1493 return attr->getValue();
1494 }
1496 /**
1497 *
1498 */
1499 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1500 const DOMString& qualifiedName,
1501 const DOMString& value)
1502 throw(DOMException)
1503 {
1504 AttrImplPtr attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1505 attr->setValue(value);
1506 attr->setOwnerElement(this);
1507 attributes.setNamedItemNS(attr);
1508 }
1510 /**
1511 *
1512 */
1513 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1514 const DOMString& localName)
1515 throw(DOMException)
1516 {
1517 attributes.removeNamedItemNS(namespaceURI, localName);
1518 }
1520 /**
1521 *
1522 */
1523 AttrPtr ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1524 const DOMString& localName)
1525 {
1526 NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1527 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1528 return (Attr *)0;
1529 AttrPtr attr = dynamic_cast<Attr *>(node.get());
1530 return attr;
1531 }
1533 /**
1534 *
1535 */
1536 AttrPtr ElementImpl::setAttributeNodeNS(AttrPtr attr)
1537 throw(DOMException)
1538 {
1539 attributes.setNamedItemNS(attr);
1540 return attr;
1541 }
1544 /**
1545 *
1546 */
1547 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1548 const DOMString& namespaceURI,
1549 const DOMString& tagName, ElementPtr elem)
1550 {
1551 if (!elem)
1552 return;
1554 if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName())
1555 list.add(elem);
1556 for (NodePtr node = elem->getFirstChild() ; node.get() ; node=node->getNextSibling())
1557 {
1558 if (node->getNodeType() != Node::ELEMENT_NODE)
1559 continue;
1560 ElementPtr childElem = dynamic_cast<Element *>(node.get());
1561 getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem);
1562 }
1563 }
1565 /**
1566 *
1567 */
1568 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1569 const DOMString& localName)
1570 {
1571 NodeList list;
1572 getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1573 return list;
1574 }
1576 /**
1577 *
1578 */
1579 bool ElementImpl::hasAttribute(const DOMString& attrName)
1580 {
1581 NodePtr node = attributes.getNamedItem(attrName);
1582 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1583 return false;
1584 return true;
1585 }
1587 /**
1588 *
1589 */
1590 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1591 const DOMString& localName)
1592 {
1593 NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1594 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1595 return false;
1596 return true;
1597 }
1599 /**
1600 *
1601 */
1602 TypeInfo &ElementImpl::getSchemaTypeInfo()
1603 {
1604 return typeInfo;
1605 }
1608 /**
1609 *
1610 */
1611 void ElementImpl::setIdAttribute(const DOMString &/*name*/,
1612 bool /*isId*/) throw (DOMException)
1613 {
1614 //fixme
1615 }
1617 /**
1618 *
1619 */
1620 void ElementImpl::setIdAttributeNS(const DOMString &/*namespaceURI*/,
1621 const DOMString &/*localName*/,
1622 bool /*isId*/) throw (DOMException)
1623 {
1624 //fixme
1625 }
1627 /**
1628 *
1629 */
1630 void ElementImpl::setIdAttributeNode(const AttrPtr /*idAttr*/,
1631 bool /*isId*/) throw (DOMException)
1632 {
1633 //fixme
1634 }
1637 //##################
1638 //# Non-API methods
1639 //##################
1642 /**
1643 *
1644 */
1645 ElementImpl::ElementImpl() : NodeImpl()
1646 {
1647 nodeType = ELEMENT_NODE;
1648 }
1650 /**
1651 *
1652 */
1653 ElementImpl::ElementImpl(DocumentImplPtr owner, const DOMString &tagName)
1654 : NodeImpl()
1655 {
1656 nodeType = ELEMENT_NODE;
1657 ownerDocument = owner;
1658 setNodeName(tagName);
1659 }
1661 /**
1662 *
1663 */
1664 ElementImpl::ElementImpl(DocumentImplPtr owner,
1665 const DOMString &/*theNamespaceURI*/,
1666 const DOMString &qualifiedName) :
1667 NodeImpl()
1668 {
1669 nodeType = ELEMENT_NODE;
1670 ownerDocument = owner;
1671 setNodeName(qualifiedName);
1672 }
1674 /**
1675 *
1676 */
1677 ElementImpl::~ElementImpl()
1678 {
1679 }
1682 /**
1683 *
1684 */
1685 void ElementImpl::normalizeNamespaces()
1686 {
1687 //printf("### NORMALIZE\n");
1689 NamedNodeMap attrs = getAttributes();
1691 //#######################################
1692 //# Pick up local namespace declarations
1693 //#######################################
1694 bindingsClear(); //Reset bindings on this node
1696 int nrAttrs = attrs.getLength();
1697 for (int i=0; i<nrAttrs ; i++)
1698 {
1699 NodePtr attrNode = attrs.item(i);
1700 if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1701 continue;
1702 AttrImplPtr attr = dynamic_cast<AttrImpl *>(attrNode.get());
1703 DOMString attrNS = attr->getNamespaceURI();
1704 DOMString attrName = attr->getLocalName();
1705 DOMString attrPrefix = attr->getPrefix();
1706 DOMString attrValue = attr->getNodeValue();
1707 if (attrName != "xmlns" && attrPrefix != "xmlns")
1708 continue;
1710 //is the namespace declaration is invalid?
1711 if (attrValue == XMLNSNAME || attrName == attrPrefix)
1712 {
1713 // Note: The prefix xmlns is used only to declare namespace bindings and
1714 // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
1715 // It must not be declared. No other prefix may be bound to this namespace name.
1717 //==> Report an error.
1718 printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n",
1719 XMLNSNAME);
1721 }
1722 else
1723 {
1724 //==> Record the namespace declaration
1725 attr->setNamespaceURI(XMLNSNAME);
1726 if (attrPrefix.size() > 0)
1727 bindingsAdd(attrPrefix, attrValue);
1728 else
1729 bindingsAdd("*", attrValue);//default
1731 }
1732 }
1735 //#######################################
1736 //# Fixup element's namespace
1737 //#######################################
1738 if ( namespaceURI.size() > 0 )
1739 {
1740 DOMString key = prefix;
1741 if (key.size() == 0)
1742 key = "*";
1743 DOMString binding = bindingsFind(key);
1744 //Element's prefix/namespace pair (or default namespace, if no prefix)
1745 // are within the scope of a binding
1746 if ( binding == namespaceURI )
1747 {
1748 //==> do nothing, declaration in scope is inherited
1750 // See section "B.1.1: Scope of a binding" for an example
1752 }
1753 else
1754 {
1756 /*
1757 ==> Create a local namespace declaration attr for this namespace,
1758 with Element's current prefix (or a default namespace, if
1759 no prefix). If there's a conflicting local declaration
1760 already present, change its value to use this namespace.
1762 See section "B.1.2: Conflicting namespace declaration" for an example
1763 */
1764 DOMString attrName = "xmlns";
1765 if (prefix.size() > 0)
1766 {
1767 attrName.append(":");
1768 attrName.append(prefix);
1769 }
1770 setAttribute(attrName, namespaceURI);
1771 // NOTE that this may break other nodes within this Element's
1772 // subtree, if they're already using this prefix.
1773 // They will be repaired when we reach them.
1774 }
1775 }
1776 else // Element has no namespace URI:
1777 {
1778 //###############################################
1779 //# Bob -- alter this from the specs a bit.
1780 //# Since the XmlReader does not set namespaces,
1781 //# do it here
1782 //###############################################
1783 DOMString localName = getLocalName();
1784 if ( localName.size()==0 )
1785 {
1786 // DOM Level 1 node
1787 /*
1788 ==> if in process of validation against a namespace aware schema
1789 (i.e XML Schema) report a fatal error: the processor can not recover
1790 in this situation.
1791 Otherwise, report an error: no namespace fixup will be performed on this node.
1792 */
1793 printf("normalizeNamespaces() error: no localName\n");
1794 }
1795 else
1796 {
1797 // Element has no pseudo-prefix
1798 //there's a conflicting local default namespace declaration already present
1799 if ( prefix.size()==0 )
1800 {
1801 //==> change its value to use this empty namespace.
1802 namespaceURI = bindingsFind("*");
1803 //setAttribute("xmlns", "");
1804 }
1805 else //#BOB . I added this.
1806 {
1807 namespaceURI = bindingsFind(prefix);
1808 }
1809 // NOTE that this may break other nodes within this Element's
1810 // subtree, if they're already using the default namespaces.
1811 // They will be repaired when we reach them.
1812 }
1813 }
1816 //#######################################
1817 //# Examine and polish the attributes
1818 //#######################################
1819 nrAttrs = attrs.getLength();
1820 for (int i=0; i<nrAttrs ; i++)// all non-namespace Attrs of Element
1821 {
1822 NodePtr attrNode = attrs.item(i);
1823 if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1824 continue;
1825 AttrPtr attr = dynamic_cast<Attr *>(attrNode.get());
1826 DOMString attrNS = attr->getNamespaceURI();
1827 DOMString attrPrefix = attr->getPrefix();
1828 DOMString attrValue = attr->getNodeValue();
1829 if (attrNS == XMLNSNAME)
1830 continue;
1832 if ( attrNS.size()>0 ) //Attr[i] has a namespace URI
1833 {
1834 DOMString attrBinding = bindingsFind(attrPrefix);
1835 /*
1836 if attribute has no prefix (default namespace decl does not apply to attributes)
1837 OR
1838 attribute prefix is not declared
1839 OR
1840 conflict: attribute has a prefix that conflicts with a binding
1841 already active in scope
1842 */
1843 if ( attrPrefix.size() == 0 || attrBinding.size() == 0)
1844 {
1845 //namespaceURI matches an in scope declaration of one or more prefixes)
1846 DOMString prefixForNS = lookupNamespacePrefix(attrNS, this);
1847 if ( prefixForNS.size() > 0 )
1848 {
1849 // pick the most local binding available;
1850 // if there is more than one pick one arbitrarily
1852 //==> change attribute's prefix.
1853 attr->setPrefix(prefixForNS);
1854 }
1855 else
1856 {
1857 // the current prefix is not null and it has no in scope declaration)
1858 if ( attrPrefix.size() > 0 || attrBinding.size() == 0 )
1859 {
1860 //==> declare this prefix
1861 DOMString newAttrName = "xmlns:";
1862 newAttrName.append(attrPrefix);
1863 setAttribute(newAttrName, attrNS);
1864 bindingsAdd(attrPrefix, attrNS);
1865 }
1866 else
1867 {
1868 // find a prefix following the pattern "NS" +index (starting at 1)
1869 // make sure this prefix is not declared in the current scope.
1870 // create a local namespace declaration attribute
1872 //==> declare this prefix
1873 char buf[16];
1874 sprintf(buf, "%d" , ownerDocument->namespaceIndex++);
1875 DOMString newPrefix = "NS";
1876 newPrefix.append(buf);
1877 DOMString newAttrName = "xmlns:";
1878 newAttrName.append(newPrefix);
1879 setAttribute(newAttrName, attrNS);
1880 bindingsAdd(newPrefix, attrNS);
1881 //==> change attribute's prefix.
1882 }
1883 }
1884 }
1885 }
1886 else // Attr has no namespace URI
1887 {
1888 // Attr has no localName
1889 if ( attr->getLocalName().size() == 0 )
1890 {
1891 // DOM Level 1 node
1892 /*
1893 ==> if in process of validation against a namespace aware schema
1894 (i.e XML Schema) report a fatal error: the processor can not recover
1895 in this situation.
1896 Otherwise, report an error: no namespace fixup will be performed on this node.
1897 */
1898 printf("normalizeNamespaces: no local name for attribute\n");
1899 }
1900 else
1901 {
1902 // attr has no namespace URI and no prefix
1903 // no action is required, since attrs don't use default
1904 //==> do nothing
1905 }
1906 }
1907 } // end for-all-Attrs
1910 //#######################################
1911 //# Recursively normalize children
1912 //#######################################
1913 for (NodePtr child=getFirstChild() ; child.get() ; child=child->getNextSibling())
1914 {
1915 if (child->getNodeType() != Node::ELEMENT_NODE)
1916 continue;
1917 ElementImplPtr childElement = dynamic_cast<ElementImpl *>(child.get());
1918 childElement->normalizeNamespaces();
1919 }
1921 }
1924 /*#########################################################################
1925 ## TextImpl
1926 #########################################################################*/
1929 /**
1930 *
1931 */
1932 TextImpl::TextImpl() : CharacterDataImpl()
1933 {
1934 nodeType = TEXT_NODE;
1935 nodeName = "#text";
1936 }
1939 /**
1940 *
1941 */
1942 TextImpl::TextImpl(DocumentImplPtr owner, const DOMString &value)
1943 : CharacterDataImpl()
1944 {
1945 nodeType = TEXT_NODE;
1946 nodeName = "#text";
1947 ownerDocument = owner;
1948 nodeValue = value;
1949 }
1952 /**
1953 *
1954 */
1955 TextImpl::~TextImpl()
1956 {
1957 }
1959 /**
1960 *
1961 */
1962 TextPtr TextImpl::splitText(unsigned long /*offset*/)
1963 throw(DOMException)
1964 {
1965 return NULL;
1966 }
1968 /**
1969 *
1970 */
1971 bool TextImpl::getIsElementContentWhitespace()
1972 {
1973 return false;
1974 }
1976 /**
1977 *
1978 */
1979 DOMString TextImpl::getWholeText()
1980 {
1981 return nodeValue;
1982 }
1985 /**
1986 *
1987 */
1988 TextPtr TextImpl::replaceWholeText(const DOMString &/*content*/)
1989 throw(DOMException)
1990 {
1991 return NULL;
1992 }
1995 /*#########################################################################
1996 ## CommentImpl
1997 #########################################################################*/
1999 /**
2000 *
2001 */
2002 CommentImpl::CommentImpl() : CharacterDataImpl()
2003 {
2004 nodeType = COMMENT_NODE;
2005 nodeName = "#comment";
2006 }
2009 /**
2010 *
2011 */
2012 CommentImpl::CommentImpl(DocumentImplPtr owner, const DOMString &value)
2013 : CharacterDataImpl()
2014 {
2015 nodeType = COMMENT_NODE;
2016 nodeName = "#comment";
2017 ownerDocument = owner;
2018 nodeValue = value;
2019 }
2022 /**
2023 *
2024 */
2025 CommentImpl::~CommentImpl()
2026 {
2027 }
2035 /*#########################################################################
2036 ## UserDataHandlerImpl
2037 #########################################################################*/
2041 /**
2042 *
2043 */
2044 UserDataHandlerImpl::UserDataHandlerImpl()
2045 {
2046 }
2049 /**
2050 *
2051 */
2052 UserDataHandlerImpl::~UserDataHandlerImpl()
2053 {
2054 }
2056 /**
2057 *
2058 */
2059 void UserDataHandlerImpl::handle(unsigned short /*operation*/,
2060 const DOMString &/*key*/,
2061 const DOMUserData */*data*/,
2062 const NodePtr /*src*/,
2063 const NodePtr /*dst*/)
2064 {
2065 //do nothing. do we need anything here?
2066 }
2070 /*#########################################################################
2071 ## DOMErrorImpl
2072 #########################################################################*/
2076 /**
2077 *
2078 */
2079 DOMErrorImpl::DOMErrorImpl()
2080 {
2081 }
2084 /**
2085 *
2086 */
2087 DOMErrorImpl::~DOMErrorImpl()
2088 {
2089 }
2091 /**
2092 *
2093 */
2094 unsigned short DOMErrorImpl::getSeverity()
2095 {
2096 return severity;
2097 }
2099 /**
2100 *
2101 */
2102 DOMString DOMErrorImpl::getMessage()
2103 {
2104 return message;
2105 }
2107 /**
2108 *
2109 */
2110 DOMString DOMErrorImpl::getType()
2111 {
2112 return type;
2113 }
2115 /**
2116 *
2117 */
2118 DOMObject *DOMErrorImpl::getRelatedException()
2119 {
2120 return NULL;
2121 }
2123 /**
2124 *
2125 */
2126 DOMObject *DOMErrorImpl::getRelatedData()
2127 {
2128 return NULL;
2129 }
2131 /**
2132 *
2133 */
2134 DOMLocator *DOMErrorImpl::getLocation()
2135 {
2136 //really should fill this in
2137 return NULL;
2138 }
2143 /*#########################################################################
2144 ## DOMErrorHandlerImpl
2145 #########################################################################*/
2149 /**
2150 *
2151 */
2152 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2153 {
2154 }
2157 /**
2158 *
2159 */
2160 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2161 {
2162 }
2164 /**
2165 *
2166 */
2167 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2168 {
2169 if (!error)
2170 return false;
2171 return true;
2172 }
2177 /*#########################################################################
2178 ## DOMLocatorImpl
2179 #########################################################################*/
2182 /**
2183 *
2184 */
2185 DOMLocatorImpl::DOMLocatorImpl()
2186 {
2187 }
2190 /**
2191 *
2192 */
2193 DOMLocatorImpl::~DOMLocatorImpl()
2194 {
2195 }
2198 /**
2199 *
2200 */
2201 long DOMLocatorImpl::getLineNumber()
2202 {
2203 return lineNumber;
2204 }
2206 /**
2207 *
2208 */
2209 long DOMLocatorImpl::getColumnNumber()
2210 {
2211 return columnNumber;
2212 }
2214 /**
2215 *
2216 */
2217 long DOMLocatorImpl::getByteOffset()
2218 {
2219 return byteOffset;
2220 }
2222 /**
2223 *
2224 */
2225 long DOMLocatorImpl::getUtf16Offset()
2226 {
2227 return utf16Offset;
2228 }
2231 /**
2232 *
2233 */
2234 NodePtr DOMLocatorImpl::getRelatedNode()
2235 {
2236 return relatedNode;
2237 }
2240 /**
2241 *
2242 */
2243 DOMString DOMLocatorImpl::getUri()
2244 {
2245 return uri;
2246 }
2250 /*#########################################################################
2251 ## DOMConfigurationImpl
2252 #########################################################################*/
2255 /**
2256 *
2257 */
2258 DOMConfigurationImpl::DOMConfigurationImpl()
2259 {
2260 }
2263 /**
2264 *
2265 */
2266 DOMConfigurationImpl::~DOMConfigurationImpl()
2267 {
2268 }
2270 /**
2271 *
2272 */
2273 void DOMConfigurationImpl::setParameter(const DOMString &/*name*/,
2274 const DOMUserData */*value*/) throw (DOMException)
2275 {
2276 }
2278 /**
2279 *
2280 */
2281 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &/*name*/)
2282 throw (DOMException)
2283 {
2284 return NULL;
2285 }
2287 /**
2288 *
2289 */
2290 bool DOMConfigurationImpl::canSetParameter(const DOMString &/*name*/,
2291 const DOMUserData */*data*/)
2292 {
2293 return false;
2294 }
2296 /**
2297 *
2298 */
2299 DOMStringList *DOMConfigurationImpl::getParameterNames()
2300 {
2301 return NULL;
2302 }
2306 /*#########################################################################
2307 ## CDATASectionImpl
2308 #########################################################################*/
2310 /**
2311 *
2312 */
2313 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2314 {
2315 nodeType = CDATA_SECTION_NODE;
2316 nodeName = "#cdata-section";
2317 }
2319 /**
2320 *
2321 */
2322 CDATASectionImpl::CDATASectionImpl(DocumentImplPtr owner, const DOMString &theValue)
2323 : TextImpl()
2324 {
2325 nodeType = CDATA_SECTION_NODE;
2326 nodeName = "#cdata-section";
2327 ownerDocument = owner;
2328 nodeValue = theValue;
2329 }
2332 /**
2333 *
2334 */
2335 CDATASectionImpl::~CDATASectionImpl()
2336 {
2337 }
2343 /*#########################################################################
2344 ## DocumentTypeImpl
2345 #########################################################################*/
2347 /**
2348 *
2349 */
2350 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2351 const DOMString& thePublicId,
2352 const DOMString& theSystemId)
2353 : NodeImpl()
2354 {
2355 nodeType = DOCUMENT_TYPE_NODE;
2356 nodeName = theName;
2357 publicId = thePublicId;
2358 systemId = theSystemId;
2359 }
2361 /**
2362 *
2363 */
2364 DocumentTypeImpl::~DocumentTypeImpl()
2365 {
2366 }
2368 /**
2369 *
2370 */
2371 DOMString DocumentTypeImpl::getName()
2372 {
2373 return nodeName;
2374 }
2376 /**
2377 *
2378 */
2379 NamedNodeMap DocumentTypeImpl::getEntities()
2380 {
2381 return entities;
2382 }
2384 /**
2385 *
2386 */
2387 NamedNodeMap DocumentTypeImpl::getNotations()
2388 {
2389 return notations;
2390 }
2392 /**
2393 *
2394 */
2395 DOMString DocumentTypeImpl::getPublicId()
2396 {
2397 return publicId;
2398 }
2400 /**
2401 *
2402 */
2403 DOMString DocumentTypeImpl::getSystemId()
2404 {
2405 return systemId;
2406 }
2408 /**
2409 *
2410 */
2411 DOMString DocumentTypeImpl::getInternalSubset()
2412 {
2413 return DOMString("");
2414 }
2421 /*#########################################################################
2422 ## NotationImpl
2423 #########################################################################*/
2427 /**
2428 *
2429 */
2430 NotationImpl::NotationImpl(DocumentImplPtr owner) : NodeImpl()
2431 {
2432 nodeType = NOTATION_NODE;
2433 ownerDocument = owner;
2434 }
2437 /**
2438 *
2439 */
2440 NotationImpl::~NotationImpl()
2441 {
2442 }
2444 /**
2445 *
2446 */
2447 DOMString NotationImpl::getPublicId()
2448 {
2449 return publicId;
2450 }
2452 /**
2453 *
2454 */
2455 DOMString NotationImpl::getSystemId()
2456 {
2457 return systemId;
2458 }
2467 /*#########################################################################
2468 ## EntityImpl
2469 #########################################################################*/
2472 /**
2473 *
2474 */
2475 EntityImpl::EntityImpl() : NodeImpl()
2476 {
2477 nodeType = ENTITY_NODE;
2478 }
2481 /**
2482 *
2483 */
2484 EntityImpl::EntityImpl(DocumentImplPtr owner) : NodeImpl()
2485 {
2486 nodeType = ENTITY_NODE;
2487 ownerDocument = owner;
2488 }
2491 /**
2492 *
2493 */
2494 EntityImpl::~EntityImpl()
2495 {
2496 }
2498 /**
2499 *
2500 */
2501 DOMString EntityImpl::getPublicId()
2502 {
2503 return publicId;
2504 }
2506 /**
2507 *
2508 */
2509 DOMString EntityImpl::getSystemId()
2510 {
2511 return systemId;
2512 }
2514 /**
2515 *
2516 */
2517 DOMString EntityImpl::getNotationName()
2518 {
2519 return notationName;
2520 }
2522 /**
2523 *
2524 */
2525 DOMString EntityImpl::getInputEncoding()
2526 {
2527 return inputEncoding;
2528 }
2530 /**
2531 *
2532 */
2533 DOMString EntityImpl::getXmlEncoding()
2534 {
2535 return xmlEncoding;
2536 }
2538 /**
2539 *
2540 */
2541 DOMString EntityImpl::getXmlVersion()
2542 {
2543 return xmlVersion;
2544 }
2551 /*#########################################################################
2552 ## EntityReferenceImpl
2553 #########################################################################*/
2557 /**
2558 *
2559 */
2560 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2561 {
2562 nodeType = ENTITY_REFERENCE_NODE;
2563 }
2566 /**
2567 *
2568 */
2569 EntityReferenceImpl::EntityReferenceImpl(DocumentImplPtr owner,
2570 const DOMString &theName)
2571 : NodeImpl()
2572 {
2573 nodeType = ENTITY_REFERENCE_NODE;
2574 nodeName = theName;
2575 ownerDocument = owner;
2576 }
2579 /**
2580 *
2581 */
2582 EntityReferenceImpl::~EntityReferenceImpl()
2583 {
2584 }
2588 /*#########################################################################
2589 ## ProcessingInstructionImpl
2590 #########################################################################*/
2595 /**
2596 *
2597 */
2598 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2599 {
2600 nodeType = PROCESSING_INSTRUCTION_NODE;
2601 }
2605 /**
2606 *
2607 */
2608 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImplPtr owner,
2609 const DOMString &target,
2610 const DOMString &data)
2611 : NodeImpl()
2612 {
2613 nodeType = PROCESSING_INSTRUCTION_NODE;
2614 ownerDocument = owner;
2615 nodeName = target;
2616 nodeValue = data;
2617 }
2620 /**
2621 *
2622 */
2623 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2624 {
2625 }
2630 /**
2631 *
2632 */
2633 DOMString ProcessingInstructionImpl::getTarget()
2634 {
2635 return nodeName;
2636 }
2638 /**
2639 *
2640 */
2641 DOMString ProcessingInstructionImpl::getData()
2642 {
2643 return nodeValue;
2644 }
2646 /**
2647 *
2648 */
2649 void ProcessingInstructionImpl::setData(const DOMString& /*val*/) throw(DOMException)
2650 {
2651 //do something here
2652 }
2660 /*#########################################################################
2661 ## DocumentFragmentImpl
2662 #########################################################################*/
2664 /**
2665 *
2666 */
2667 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2668 {
2669 nodeType = DOCUMENT_FRAGMENT_NODE;
2670 nodeName = "#document-fragment";
2671 }
2674 /**
2675 *
2676 */
2677 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImplPtr owner) : NodeImpl()
2678 {
2679 nodeType = DOCUMENT_FRAGMENT_NODE;
2680 nodeName = "#document-fragment";
2681 ownerDocument = owner;
2682 }
2685 /**
2686 *
2687 */
2688 DocumentFragmentImpl::~DocumentFragmentImpl()
2689 {
2690 }
2697 /*#########################################################################
2698 ## DocumentImpl
2699 #########################################################################*/
2703 /**
2704 *
2705 */
2706 DocumentTypePtr DocumentImpl::getDoctype()
2707 {
2708 return doctype;
2709 }
2711 /**
2712 *
2713 */
2714 DOMImplementation *DocumentImpl::getImplementation()
2715 {
2716 return parent;
2717 }
2719 /**
2720 *
2721 */
2722 ElementPtr DocumentImpl::getDocumentElement()
2723 {
2724 return documentElement;
2725 }
2727 /**
2728 *
2729 */
2730 ElementPtr DocumentImpl::createElement(const DOMString& tagName)
2731 throw(DOMException)
2732 {
2733 ElementPtr elem = new ElementImpl(this, tagName);
2734 return elem;
2735 }
2737 /**
2738 *
2739 */
2740 DocumentFragmentPtr DocumentImpl::createDocumentFragment()
2741 {
2742 DocumentFragmentPtr frag = new DocumentFragmentImpl(this);
2743 return frag;
2744 }
2746 /**
2747 *
2748 */
2749 TextPtr DocumentImpl::createTextNode(const DOMString& data)
2750 {
2751 TextPtr text = new TextImpl(this, data);
2752 return text;
2753 }
2755 /**
2756 *
2757 */
2758 CommentPtr DocumentImpl::createComment(const DOMString& data)
2759 {
2760 CommentPtr comment = new CommentImpl(this, data);
2761 return comment;
2762 }
2764 /**
2765 *
2766 */
2767 CDATASectionPtr DocumentImpl::createCDATASection(const DOMString& data)
2768 throw(DOMException)
2769 {
2770 CDATASectionPtr cdata = new CDATASectionImpl(this, data);
2771 return cdata;
2772 }
2774 /**
2775 *
2776 */
2777 ProcessingInstructionPtr
2778 DocumentImpl::createProcessingInstruction(const DOMString& target,
2779 const DOMString& data)
2780 throw(DOMException)
2781 {
2782 ProcessingInstructionPtr pi =
2783 new ProcessingInstructionImpl(this, target, data);
2784 return pi;
2785 }
2787 /**
2788 *
2789 */
2790 AttrPtr DocumentImpl::createAttribute(const DOMString& attrName)
2791 throw(DOMException)
2792 {
2793 AttrPtr attr = new AttrImpl(this, attrName);
2794 return attr;
2795 }
2797 /**
2798 *
2799 */
2800 EntityReferencePtr DocumentImpl::createEntityReference(const DOMString& erName)
2801 throw(DOMException)
2802 {
2803 EntityReferencePtr ref = new EntityReferenceImpl(this, erName);
2804 return ref;
2805 }
2808 /**
2809 *
2810 */
2811 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2812 {
2813 NodeList list;
2814 ElementImpl::getElementsByTagNameRecursive(list,
2815 tagname, documentElement);
2816 return list;
2817 }
2820 /**
2821 *
2822 */
2823 NodePtr DocumentImpl::importNode(const NodePtr /*importedNode*/,
2824 bool /*deep*/)
2825 throw(DOMException)
2826 {
2827 return NULL;
2828 }
2830 /**
2831 *
2832 */
2833 ElementPtr DocumentImpl::createElementNS(const DOMString& namespaceURI,
2834 const DOMString& qualifiedName)
2835 throw(DOMException)
2836 {
2837 ElementPtr elem = new ElementImpl(this, namespaceURI, qualifiedName);
2838 return elem;
2839 }
2841 /**
2842 *
2843 */
2844 AttrPtr DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2845 const DOMString& qualifiedName)
2846 throw(DOMException)
2847 {
2848 AttrPtr attr = new AttrImpl(this, namespaceURI, qualifiedName);
2849 return attr;
2850 }
2853 /**
2854 *
2855 */
2856 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2857 const DOMString& localName)
2858 {
2859 NodeList list;
2860 ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2861 localName, documentElement);
2862 return list;
2863 }
2865 /**
2866 *
2867 */
2868 ElementPtr DocumentImpl::getElementById(const DOMString& elementId)
2869 {
2870 for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2871 if (entry->name == elementId)
2872 return entry->elem;
2873 return NULL;
2874 }
2877 /**
2878 *
2879 */
2880 DOMString DocumentImpl::getInputEncoding()
2881 {
2882 return inputEncoding;
2883 }
2886 /**
2887 *
2888 */
2889 DOMString DocumentImpl::getXmlEncoding()
2890 {
2891 return xmlEncoding;
2892 }
2894 /**
2895 *
2896 */
2897 bool DocumentImpl::getXmlStandalone()
2898 {
2899 return xmlStandalone;
2900 }
2902 /**
2903 *
2904 */
2905 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2906 {
2907 xmlStandalone = val;
2908 }
2910 /**
2911 *
2912 */
2913 DOMString DocumentImpl::getXmlVersion()
2914 {
2915 return xmlVersion;
2916 }
2918 /**
2919 *
2920 */
2921 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2922 {
2923 xmlVersion = version;
2924 }
2926 /**
2927 *
2928 */
2929 bool DocumentImpl::getStrictErrorChecking()
2930 {
2931 return strictErrorChecking;
2932 }
2934 /**
2935 *
2936 */
2937 void DocumentImpl::setStrictErrorChecking(bool val)
2938 {
2939 strictErrorChecking = val;
2940 }
2943 /**
2944 *
2945 */
2946 DOMString DocumentImpl::getDocumentURI()
2947 {
2948 return documentURI;
2949 }
2951 /**
2952 *
2953 */
2954 void DocumentImpl::setDocumentURI(const DOMString &/*uri*/)
2955 {
2956 //documentURI = stringCache(uri);
2957 }
2959 /**
2960 *
2961 */
2962 NodePtr DocumentImpl::adoptNode(const NodePtr source) throw (DOMException)
2963 {
2964 return (NodePtr )source;
2965 }
2967 /**
2968 *
2969 */
2970 DOMConfiguration *DocumentImpl::getDomConfig()
2971 {
2972 return domConfig;
2973 }
2975 /**
2976 *
2977 */
2978 void DocumentImpl::normalizeDocument()
2979 {
2980 //i assume that this means adjusting namespaces & prefixes
2981 if (documentElement.get())
2982 documentElement->normalizeNamespaces();
2983 }
2985 /**
2986 *
2987 */
2988 NodePtr DocumentImpl::renameNode(const NodePtr node,
2989 const DOMString &/*namespaceURI*/,
2990 const DOMString &qualifiedName)
2991 throw (DOMException)
2992 {
2993 NodeImplPtr nodeImpl = dynamic_cast<NodeImpl *> (node.get());
2994 nodeImpl->setNodeName(qualifiedName);
2995 return node;
2996 }
3000 //##################
3001 //# Non-API methods
3002 //##################
3004 /**
3005 *
3006 */
3007 DocumentImpl::DocumentImpl(const DOMImplementation *domImpl,
3008 const DOMString &/*theNamespaceURI*/,
3009 const DOMString &theQualifiedName,
3010 const DocumentTypePtr theDoctype) : NodeImpl()
3011 {
3012 nodeType = DOCUMENT_NODE;
3013 nodeName = "#document";
3014 parent = (DOMImplementation *)domImpl;
3015 //documentURI = stringCache(theNamespaceURI);
3016 qualifiedName = theQualifiedName;
3017 if (theDoctype.get()) //only assign if not null.
3018 doctype = theDoctype;
3019 else
3020 doctype = new DocumentTypeImpl("", "", "");
3021 documentElement = new ElementImpl(this, "root");
3022 namespaceIndex = 0;
3023 }
3026 /**
3027 *
3028 */
3029 DocumentImpl::~DocumentImpl()
3030 {
3031 documentElement = NULL;
3032 }
3045 } //namespace dom
3046 } //namespace w3c
3047 } //namespace org
3051 /*#########################################################################
3052 ## E N D O F F I L E
3053 #########################################################################*/