NodeImpl.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:16k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: NodeImpl.cpp,v 1.35 2001/10/25 21:47:14 peiyongz Exp $
  58.  */
  59. // This class doesn't support having any children, and implements the behavior
  60. // of an empty NodeList as far getChildNodes is concerned.
  61. // The ParentNode subclass overrides this behavior.
  62. #include "NodeImpl.hpp"
  63. #include "AttrImpl.hpp"
  64. #include "DOM_DOMException.hpp"
  65. #include "DOM_Node.hpp"
  66. #include "DOM_DOMImplementation.hpp"
  67. #include "DOMString.hpp"
  68. #include "DStringPool.hpp"
  69. #include "DocumentImpl.hpp"
  70. #include "NodeIDMap.hpp"
  71. #include "stdio.h"
  72. #include "TextImpl.hpp"
  73. static DOMString *s_xml = null;
  74. static DOMString *s_xmlURI = null;
  75. static DOMString *s_xmlns = null;
  76. static DOMString *s_xmlnsURI = null;
  77. static XMLRegisterCleanup nodeImplCleanup;
  78. const unsigned short NodeImpl::READONLY     = 0x1<<0;
  79. const unsigned short NodeImpl::SYNCDATA     = 0x1<<1;
  80. const unsigned short NodeImpl::SYNCCHILDREN = 0x1<<2;
  81. const unsigned short NodeImpl::OWNED        = 0x1<<3;
  82. const unsigned short NodeImpl::FIRSTCHILD   = 0x1<<4;
  83. const unsigned short NodeImpl::SPECIFIED    = 0x1<<5;
  84. const unsigned short NodeImpl::IGNORABLEWS  = 0x1<<6;
  85. const unsigned short NodeImpl::SETVALUE     = 0x1<<7;
  86. const unsigned short NodeImpl::ID_ATTR      = 0x1<<8;
  87. const unsigned short NodeImpl::USERDATA     = 0x1<<9;
  88. const unsigned short NodeImpl::HASSTRING    = 0x1<<10;
  89. NodeImpl::NodeImpl(DocumentImpl *ownerDoc)
  90. {
  91.     this->flags = 0;
  92.     // as long as we do not have any owner, ownerNode is our ownerDocument
  93.     this->ownerNode  = ownerDoc;
  94.     this->nodeRefCount = 0;
  95.     NodeImpl::gLiveNodeImpls++;
  96.     NodeImpl::gTotalNodeImpls++;
  97. };
  98. // This only makes a shallow copy, cloneChildren must also be called for a
  99. // deep clone
  100. NodeImpl::NodeImpl(const NodeImpl &other) {
  101.     this->flags = other.flags;
  102.     this->isReadOnly(false);
  103.     this->nodeRefCount = 0;
  104.     NodeImpl::gLiveNodeImpls++;
  105.     NodeImpl::gTotalNodeImpls++;
  106.     // Need to break the association w/ original parent
  107.     //    this->ownerNode = other.getOwnerDocument(); this doesn't work???
  108.     this->ownerNode = ((NodeImpl*)&other)->getOwnerDocument();
  109.     this->isOwned(false);
  110. };
  111. int  NodeImpl::gLiveNodeImpls = 0;         // Counters for debug & tuning.
  112. int  NodeImpl::gTotalNodeImpls= 0;
  113. NodeImpl::~NodeImpl() {
  114. if (hasUserData())
  115. {
  116. setUserData(null);
  117. }
  118.     NodeImpl::gLiveNodeImpls--;
  119. };
  120. // Dynamic Cast substitute functions
  121. bool NodeImpl::isAttrImpl()              {return false;};
  122. bool NodeImpl::isCDATASectionImpl()      {return false;};
  123. bool NodeImpl::isDocumentFragmentImpl()  {return false;};
  124. bool NodeImpl::isDocumentImpl()          {return false;};
  125. bool NodeImpl::isDocumentTypeImpl()      {return false;};
  126. bool NodeImpl::isElementImpl()           {return false;};
  127. bool NodeImpl::isEntityReference()       {return false;};
  128. bool NodeImpl::isTextImpl()              {return false;};
  129. void NodeImpl::changed() {
  130.     // we do not actually store this information on every node, we only
  131.     // have a global indicator on the Document. Doing otherwise cost us too
  132.     // much for little gain.
  133.     getDocument()->changed();
  134. }
  135. int NodeImpl::changes()
  136. {
  137.     // we do not actually store this information on every node, we only
  138.     // have a global indicator on the Document. Doing otherwise cost us too
  139.     // much for little gain.
  140.     return getDocument()->changes();
  141. };
  142. NodeImpl * NodeImpl::appendChild(NodeImpl *newChild)
  143. {
  144.     return insertBefore(newChild, null);
  145. };
  146. //  NodeImpl::deleteIf is called when a node's reference count goes
  147. //  to 0.  It is separate function from removeRef because removeRef
  148. //  is likely to be in-lined.
  149. //
  150. //  See comments at RefCountedImpl::removeRef().
  151. //
  152. void NodeImpl::deleteIf(NodeImpl *thisNode)
  153. {
  154.     if (thisNode == 0)
  155.         return;
  156.     if (thisNode->isOwned())
  157.         return;
  158.     // Delete this node.  There should be no siblings, as the DOM
  159.     //  supports no node operations that would detach a node from
  160.     //  its parent while retaining siblings.
  161.     //  The target node may have children, in which case they must
  162.     //  be removed from this node before deleting this node.
  163.     // First, if this node is an ID attribute, we need to remove it
  164.     // from the hashtable of element IDs before removing the Attrs
  165.     //   children.  This is because the Attr's children Text nodes
  166.     //   contain the attr's value, which is the hash table key.
  167.     //
  168.     if (thisNode->isAttrImpl() && ((AttrImpl *)thisNode->isIdAttr()))
  169.     {
  170.         ((AttrImpl *)thisNode)->getOwnerDocument() ->
  171.             getNodeIDMap()->remove((AttrImpl *)thisNode);
  172.     }
  173.     thisNode->isReadOnly(false);   // removeChild requires node not be readonly.
  174.     NodeImpl *theNextChild;
  175.     for (NodeImpl *child = thisNode->getFirstChild(); child != 0;
  176.          child=theNextChild)
  177.     {
  178.         theNextChild = child->getNextSibling();
  179.         thisNode->removeChild(child);
  180.         if (child->nodeRefCount == 0)
  181.             deleteIf(child);
  182.     }
  183.     delete thisNode;
  184. };
  185. NamedNodeMapImpl * NodeImpl::getAttributes() {
  186.     return 0;                   // overridden in ElementImpl
  187. };
  188. NodeListImpl *NodeImpl::getChildNodes() {
  189.     return this;                // overridden in ParentNode
  190. };
  191. NodeImpl * NodeImpl::getFirstChild() {
  192.     return 0;                   // overridden in ParentNode
  193. };
  194. NodeImpl * NodeImpl::getLastChild()
  195. {
  196.     return 0;                   // overridden in ParentNode
  197. };
  198. unsigned int NodeImpl::getLength() {
  199.     return 0;                   // overridden in ParentNode
  200. };
  201. NodeImpl * NodeImpl::getNextSibling() {
  202.     return null;                // overridden in ChildNode
  203. };
  204. DOMString NodeImpl::getNodeValue()
  205. {
  206.     return null;                // overridden in some subclasses
  207. };
  208. DocumentImpl *NodeImpl::getOwnerDocument()
  209. {
  210.     // if we have an owner simply forward the request
  211.     // otherwise ownerNode is our ownerDocument
  212.     if (isOwned()) {
  213.         return ownerNode->getDocument();
  214.     } else {
  215.         return (DocumentImpl *) ownerNode;
  216.     }
  217. };
  218. // unlike getOwnerDocument this is not overriden by DocumentImpl to return null
  219. DocumentImpl *NodeImpl::getDocument()
  220. {
  221.     // if we have an owner simply forward the request
  222.     // otherwise ownerNode is our ownerDocument
  223.     if (isOwned()) {
  224.         return ownerNode->getDocument();
  225.     } else {
  226.         return (DocumentImpl *) ownerNode;
  227.     }
  228. };
  229. void NodeImpl::setOwnerDocument(DocumentImpl *doc) {
  230.     // if we have an owner we rely on it to have it right
  231.     // otherwise ownerNode is our ownerDocument
  232.     if (!isOwned()) {
  233.         ownerNode = doc;
  234.     }
  235. }
  236. NodeImpl * NodeImpl::getParentNode()
  237. {
  238.     return null;                // overridden in ChildNode
  239. };
  240. NodeImpl*  NodeImpl::getPreviousSibling()
  241. {
  242.     return null;                // overridden in ChildNode
  243. };
  244. void *NodeImpl::getUserData()
  245. {
  246. return (hasUserData()) ? getOwnerDocument()->getUserData(this) : null;
  247. };
  248. bool NodeImpl::hasChildNodes()
  249. {
  250.     return false;
  251. };
  252. NodeImpl *NodeImpl::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {
  253.     throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
  254.     return 0;
  255. };
  256. NodeImpl *NodeImpl::item(unsigned int index) {
  257.     return 0;
  258. };
  259. NodeImpl *NodeImpl::removeChild(NodeImpl *oldChild)
  260. {
  261.     throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
  262.     return 0;
  263. };
  264. NodeImpl *NodeImpl::replaceChild(NodeImpl *newChild, NodeImpl *oldChild)
  265. {
  266.     throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,null);
  267.     return 0;
  268. };
  269.   void NodeImpl::referenced()
  270.   {
  271.       RefCountedImpl::addRef(this->getOwnerDocument());
  272.   };
  273.   //
  274.   //    unreferenced  will be called whenever the refernce count on
  275.   //            this node goes from 1 to 0.  This node will only be
  276.   //            directly deleted here  (by deleteIf) if it is outside
  277.   //            of the document tree.
  278.   //
  279.   void NodeImpl::unreferenced()
  280.   {
  281.       DocumentImpl *doc = this->getOwnerDocument();
  282.       deleteIf(this);       // This gets nodes outside of the document -
  283.       //   deleteIf() deletes only if the parent
  284.       //   node is null.
  285.       // If this was the last external reference within the document,
  286.       //    the entire document will be deleted as well.
  287.       RefCountedImpl::removeRef(doc);
  288.   };
  289. void NodeImpl::setNodeValue(const DOMString &val)
  290. {
  291.     if (isReadOnly())
  292.         throw DOM_DOMException(DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
  293.                                null);
  294.     // Default behavior is to do nothing, overridden in some subclasses
  295. };
  296. void NodeImpl::setReadOnly(bool readOnl, bool deep)
  297. {
  298.     this->isReadOnly(readOnl);
  299.     // by default we do not have children, so deep is meaningless
  300.     // this is overridden by ParentNode
  301. }
  302. void NodeImpl::setUserData(void * val)
  303. {
  304. getOwnerDocument()->setUserData(this, val);
  305. if (val)
  306. hasUserData(true);
  307. else
  308. hasUserData(false);
  309. };
  310. DOMString NodeImpl::toString()
  311. {
  312. return DOMString("[")+getNodeName()+": "+getNodeValue()+"]";
  313. // return getNodeName();
  314. };
  315. //Introduced in DOM Level 2
  316. void NodeImpl::normalize()
  317. {
  318.     // does nothing by default, overridden by subclasses
  319. };
  320. bool NodeImpl::supports(const DOMString &feature, const DOMString &version)
  321. {
  322.     return DOM_DOMImplementation::getImplementation().hasFeature(feature, version);
  323. }
  324. DOMString NodeImpl::getNamespaceURI()
  325. {
  326.     return 0;
  327. }
  328. DOMString NodeImpl::getPrefix()
  329. {
  330.     return 0;
  331. }
  332. DOMString NodeImpl::getLocalName()
  333. {
  334.     return 0;
  335. }
  336. void NodeImpl::setPrefix(const DOMString &fPrefix)
  337. {
  338.     throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR,null);
  339. }
  340. DOMString NodeImpl::getXmlnsString() {
  341.     return DStringPool::getStaticString("xmlns"
  342.                                       , &s_xmlns
  343.                                       , reinitNodeImpl
  344.                                       , nodeImplCleanup
  345.                                       );
  346. }
  347. DOMString NodeImpl::getXmlnsURIString() {
  348.     return DStringPool::getStaticString("http://www.w3.org/2000/xmlns/"
  349.                                       , &s_xmlnsURI
  350.                                       , reinitNodeImpl
  351.                                       , nodeImplCleanup
  352.                                         );
  353. }
  354. DOMString NodeImpl::getXmlString() {
  355.     return DStringPool::getStaticString("xml"
  356.                                       , &s_xml
  357.                                       , reinitNodeImpl
  358.                                       , nodeImplCleanup
  359.                                       );
  360. }
  361. DOMString NodeImpl::getXmlURIString() {
  362.     return DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace"
  363.                                       , &s_xmlURI
  364.                                       , reinitNodeImpl
  365.                                       , nodeImplCleanup
  366.                                         );
  367. }
  368. //Return a URI mapped from the given prefix and namespaceURI as below
  369. // prefix   namespaceURI output
  370. //---------------------------------------------------
  371. // "xml"      xmlURI            xmlURI
  372. // "xml"    otherwise         NAMESPACE_ERR
  373. // "xmlns"    xmlnsURI          xmlnsURI (nType = ATTRIBUTE_NODE only)
  374. // "xmlns"    otherwise         NAMESPACE_ERR (nType = ATTRIBUTE_NODE only)
  375. //   != null   null or ""        NAMESPACE_ERR
  376. // else       any      namesapceURI
  377. const DOMString& NodeImpl::mapPrefix(const DOMString &prefix,
  378.                                      const DOMString &namespaceURI, short nType)
  379. {
  380.     DOMString xml = DStringPool::getStaticString("xml"
  381.                                                , &s_xml
  382.                                                , reinitNodeImpl
  383.                                                , nodeImplCleanup
  384.                                                );
  385.     DOMString xmlURI = DStringPool::getStaticString("http://www.w3.org/XML/1998/namespace"
  386.                                                   , &s_xmlURI
  387.                                                   , reinitNodeImpl
  388.                                                   , nodeImplCleanup
  389.                                                   );
  390.     DOMString xmlns = DStringPool::getStaticString("xmlns"
  391.                                                  , &s_xmlns
  392.                                                  , reinitNodeImpl
  393.                                                  , nodeImplCleanup
  394.                                                  );
  395.     DOMString xmlnsURI = DStringPool::getStaticString("http://www.w3.org/2000/xmlns/"
  396.                                                     , &s_xmlnsURI
  397.                                                     , reinitNodeImpl
  398.                                                     , nodeImplCleanup
  399.                                                     );
  400.     if (prefix == null)
  401.         return namespaceURI;
  402.     if (prefix.equals(xml)) {
  403.         if (namespaceURI.equals(xmlURI))
  404.             return *s_xmlURI;
  405.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  406.     } else if (nType == DOM_Node::ATTRIBUTE_NODE && prefix.equals(xmlns)) {
  407.         if (namespaceURI.equals(xmlnsURI))
  408.             return *s_xmlnsURI;
  409.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  410.     } else if (namespaceURI == null || namespaceURI.length() == 0) {
  411.         throw DOM_DOMException(DOM_DOMException::NAMESPACE_ERR, null);
  412.     } else
  413.         return namespaceURI;
  414.     return namespaceURI;
  415. }
  416. // -----------------------------------------------------------------------
  417. //  Notification that lazy data has been deleted
  418. // -----------------------------------------------------------------------
  419. void NodeImpl::reinitNodeImpl() {
  420.     delete s_xml;
  421.     s_xml = 0;
  422.     delete s_xmlURI;
  423.     s_xmlURI = 0;
  424.     delete s_xmlns;
  425.     s_xmlns = 0;
  426.     delete s_xmlnsURI;
  427.     s_xmlnsURI = 0;
  428. }