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