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

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 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) 2001, 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.  * $Log: IDTreeWalkerImpl.cpp,v $
  58.  * Revision 1.3  2001/06/04 20:11:53  tng
  59.  * IDOM: Complete IDNodeIterator, IDTreeWalker, IDNodeFilter.
  60.  *
  61.  * Revision 1.2  2001/05/11 13:26:00  tng
  62.  * Copyright update.
  63.  *
  64.  * Revision 1.1.1.1  2001/04/03 00:14:35  andyh
  65.  * IDOM
  66.  *
  67.  */
  68. #include "IDTreeWalkerImpl.hpp"
  69. #include "IDOM_Document.hpp"
  70. #include "IDOM_DOMException.hpp"
  71. #include "IDDocumentImpl.hpp"
  72. /** constructor */
  73. IDTreeWalkerImpl::IDTreeWalkerImpl (
  74.                                 IDOM_Node* root,
  75.                                 unsigned long whatToShow,
  76.                                 IDOM_NodeFilter* nodeFilter,
  77.                                 bool expandEntityRef)
  78. :   fCurrentNode(root),
  79.     fRoot(root),
  80.     fWhatToShow(whatToShow),
  81.     fNodeFilter(nodeFilter),
  82.     fExpandEntityReferences(expandEntityRef)
  83. {
  84. }
  85. IDTreeWalkerImpl::IDTreeWalkerImpl (const IDTreeWalkerImpl& twi)
  86. : fCurrentNode(twi.fCurrentNode),
  87.     fRoot(twi.fRoot),
  88.     fWhatToShow(twi.fWhatToShow),
  89.     fNodeFilter(twi.fNodeFilter),
  90.     fExpandEntityReferences(twi.fExpandEntityReferences)
  91. {
  92. }
  93. IDTreeWalkerImpl& IDTreeWalkerImpl::operator= (const IDTreeWalkerImpl& twi) {
  94.     if (this != &twi)
  95.     {
  96.         fCurrentNode            = twi.fCurrentNode;
  97.         fRoot                   = twi.fRoot;
  98.         fWhatToShow             = twi.fWhatToShow;
  99.         fNodeFilter             = twi.fNodeFilter;
  100. fExpandEntityReferences = twi.fExpandEntityReferences;
  101.     }
  102.     return *this;
  103. }
  104. /** Return the whatToShow value */
  105. unsigned long IDTreeWalkerImpl::getWhatToShow () {
  106.     return fWhatToShow;
  107. }
  108. /** Return the NodeFilter */
  109. IDOM_NodeFilter* IDTreeWalkerImpl::getFilter () {
  110.     return fNodeFilter;
  111. }
  112. /** Get the expandEntity reference flag. */
  113. bool IDTreeWalkerImpl::getExpandEntityReferences() {
  114.     return fExpandEntityReferences;
  115. }
  116. /** Return the current Node. */
  117. IDOM_Node* IDTreeWalkerImpl::getCurrentNode () {
  118.     return fCurrentNode;
  119. }
  120. /** Return the current Node. */
  121. void IDTreeWalkerImpl::setCurrentNode (IDOM_Node* node) {
  122.     fCurrentNode = node;
  123. }
  124. /** Return the parent Node from the current node,
  125.  *  after applying filter, whatToshow.
  126.  *  If result is not null, set the current Node.
  127.  */
  128. IDOM_Node* IDTreeWalkerImpl::parentNode () {
  129.     if (!fCurrentNode) return 0;
  130.     IDOM_Node* node = getParentNode(fCurrentNode);
  131.     if (node != 0) {
  132.         fCurrentNode = node;
  133.     }
  134.     return node;
  135. }
  136. /** Return the first child Node from the current node,
  137.  *  after applying filter, whatToshow.
  138.  *  If result is not null, set the current Node.
  139.  */
  140. IDOM_Node* IDTreeWalkerImpl::firstChild () {
  141.     if (!fCurrentNode) return 0;
  142.     IDOM_Node* node = getFirstChild(fCurrentNode);
  143.     if (node != 0) {
  144.         fCurrentNode = node;
  145.     }
  146.     return node;
  147. }
  148. /** Return the last child Node from the current node,
  149.  *  after applying filter, whatToshow.
  150.  *  If result is not null, set the current Node.
  151.  */
  152. IDOM_Node* IDTreeWalkerImpl::lastChild () {
  153.     if (!fCurrentNode) return 0;
  154.     IDOM_Node* node = getLastChild(fCurrentNode);
  155.     if (node != 0) {
  156.         fCurrentNode = node;
  157.     }
  158.     return node;
  159. }
  160. /** Return the previous sibling Node from the current node,
  161.  *  after applying filter, whatToshow.
  162.  *  If result is not null, set the current Node.
  163.  */
  164. IDOM_Node* IDTreeWalkerImpl::previousSibling () {
  165.     if (!fCurrentNode) return 0;
  166.     IDOM_Node* node = getPreviousSibling(fCurrentNode);
  167.     if (node != 0) {
  168.         fCurrentNode = node;
  169.     }
  170.     return node;
  171. }
  172. /** Return the next sibling Node from the current node,
  173.  *  after applying filter, whatToshow.
  174.  *  If result is not null, set the current Node.
  175.  */
  176. IDOM_Node* IDTreeWalkerImpl::nextSibling () {
  177.     if (!fCurrentNode) return 0;
  178.     IDOM_Node* node = getNextSibling(fCurrentNode);
  179.     if (node != 0) {
  180.         fCurrentNode = node;
  181.     }
  182.     return node;
  183. }
  184. /** Return the previous Node from the current node,
  185.  *  after applying filter, whatToshow.
  186.  *  If result is not null, set the current Node.
  187.  */
  188. IDOM_Node* IDTreeWalkerImpl::previousNode () {
  189.     if (!fCurrentNode) return 0;
  190.     // get sibling
  191.     IDOM_Node* node = getPreviousSibling(fCurrentNode);
  192.     if (node == 0) {
  193.         node = getParentNode(fCurrentNode);
  194.         if ( node != 0) {
  195.             fCurrentNode = node;
  196.         }
  197.         return node;
  198.     }
  199.     else {
  200.         // get the lastChild of result.
  201.         IDOM_Node* lastChild  = getLastChild(node);
  202.         // if there is a lastChild which passes filters return it.
  203.         if (lastChild != 0) {
  204.             fCurrentNode = lastChild;
  205.         }
  206.         else {
  207.             fCurrentNode = node;
  208.         }
  209.         return fCurrentNode;
  210.     }
  211. }
  212. /** Return the next Node from the current node,
  213.  *  after applying filter, whatToshow.
  214.  *  If result is not null, set the current Node.
  215.  */
  216. IDOM_Node* IDTreeWalkerImpl::nextNode () {
  217.     if (!fCurrentNode) return 0;
  218.     IDOM_Node* node = getFirstChild(fCurrentNode);
  219.     if (node != 0) {
  220.         fCurrentNode = node;
  221.         return node;
  222.     }
  223.     else {
  224.         node = getNextSibling(fCurrentNode);
  225.         if (node != 0) {
  226.             fCurrentNode = node;
  227.             return node;
  228.         }
  229.         else {
  230.             // return parent's 1st sibling.
  231.             IDOM_Node* parent = getParentNode(fCurrentNode);
  232.             while ( parent != 0) {
  233.                 node = getNextSibling(parent);
  234.                 if (node != 0) {
  235.                     fCurrentNode = node;
  236.                     return node;
  237.                 } else {
  238.                     parent = getParentNode(parent);
  239.                 }
  240.             }
  241.             return node;
  242.         }
  243.     }
  244. }
  245. /** Internal function.
  246.  *  Return the parent Node, from the input node
  247.  *  after applying filter, whatToshow.
  248.  *  The current node is not consulted or set.
  249.  */
  250. IDOM_Node* IDTreeWalkerImpl::getParentNode (IDOM_Node* node) {
  251.     if (!node || node == fRoot) return 0;
  252.     IDOM_Node* newNode = node->getParentNode();
  253.     if (!newNode)  return 0;
  254.     short accept = acceptNode(newNode);
  255.     if (accept == IDOM_NodeFilter::FILTER_ACCEPT)
  256.         return newNode;
  257.     return getParentNode(newNode);
  258. }
  259. /** Internal function.
  260.  *  Return the nextSibling Node, from the input node
  261.  *  after applying filter, whatToshow.
  262.  *  The current node is not consulted or set.
  263.  */
  264. IDOM_Node* IDTreeWalkerImpl::getNextSibling (IDOM_Node* node) {
  265.     if (!node || node == fRoot) return 0;
  266.     IDOM_Node* newNode = node->getNextSibling();
  267.     if (!newNode) {
  268.         newNode = node->getParentNode();
  269.         if (!newNode || node == fRoot)  return 0;
  270.         short parentAccept = acceptNode(newNode);
  271.         if (parentAccept == IDOM_NodeFilter::FILTER_SKIP) {
  272.             return getNextSibling(newNode);
  273.         }
  274.         return 0;
  275.     }
  276.     short accept = acceptNode(newNode);
  277.     if (accept == IDOM_NodeFilter::FILTER_ACCEPT)
  278.         return newNode;
  279.     else
  280.     if (accept == IDOM_NodeFilter::FILTER_SKIP) {
  281.         IDOM_Node* fChild =  getFirstChild(newNode);
  282.         if (!fChild) {
  283.             return getNextSibling(newNode);
  284.         }
  285.         return fChild;
  286.     }
  287.     return getNextSibling(newNode);
  288. }
  289. /** Internal function.
  290.  *  Return the previous sibling Node, from the input node
  291.  *  after applying filter, whatToshow.
  292.  *  The current node is not consulted or set.
  293.  */
  294. IDOM_Node* IDTreeWalkerImpl::getPreviousSibling (IDOM_Node* node) {
  295.     if (!node || node == fRoot) return 0;
  296.     IDOM_Node* newNode = node->getPreviousSibling();
  297.     if (!newNode) {
  298.         newNode = node->getParentNode();
  299.         if (!newNode || node == fRoot)  return 0;
  300.         short parentAccept = acceptNode(newNode);
  301.         if (parentAccept == IDOM_NodeFilter::FILTER_SKIP) {
  302.             return getPreviousSibling(newNode);
  303.         }
  304.         return 0;
  305.     }
  306.     short accept = acceptNode(newNode);
  307.     if (accept == IDOM_NodeFilter::FILTER_ACCEPT)
  308.         return newNode;
  309.     else
  310.     if (accept == IDOM_NodeFilter::FILTER_SKIP) {
  311.         IDOM_Node* fChild =  getLastChild(newNode);
  312.         if (!fChild) {
  313.             return getPreviousSibling(newNode);
  314.         }
  315.         return fChild;
  316.     }
  317.     return getPreviousSibling(newNode);
  318. }
  319. /** Internal function.
  320.  *  Return the first child Node, from the input node
  321.  *  after applying filter, whatToshow.
  322.  *  The current node is not consulted or set.
  323.  */
  324. IDOM_Node* IDTreeWalkerImpl::getFirstChild (IDOM_Node* node) {
  325.     if (!node) return 0;
  326.     IDOM_Node* newNode = node->getFirstChild();
  327.     if (!newNode)  return 0;
  328.     short accept = acceptNode(newNode);
  329.     if (accept == IDOM_NodeFilter::FILTER_ACCEPT)
  330.         return newNode;
  331.     else
  332.     if (accept == IDOM_NodeFilter::FILTER_SKIP
  333.         && newNode->hasChildNodes())
  334.     {
  335.         return getFirstChild(newNode);
  336.     }
  337.     return getNextSibling(newNode);
  338. }
  339. /** Internal function.
  340.  *  Return the last child Node, from the input node
  341.  *  after applying filter, whatToshow.
  342.  *  The current node is not consulted or set.
  343.  */
  344. IDOM_Node* IDTreeWalkerImpl::getLastChild (IDOM_Node* node) {
  345.     if (!node) return 0;
  346.     IDOM_Node* newNode = node->getLastChild();
  347.     if (!newNode)  return 0;
  348.     short accept = acceptNode(newNode);
  349.     if (accept == IDOM_NodeFilter::FILTER_ACCEPT)
  350.         return newNode;
  351.     else
  352.     if (accept == IDOM_NodeFilter::FILTER_SKIP
  353.         && newNode->hasChildNodes())
  354.     {
  355.         return getLastChild(newNode);
  356.     }
  357.     return getPreviousSibling(newNode);
  358. }
  359. /** The node is accepted if it passes the whatToShow and the filter. */
  360. short IDTreeWalkerImpl::acceptNode (IDOM_Node* node) {
  361.     if (fNodeFilter == 0) {
  362.         if ( ( fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)
  363.         {
  364.             return IDOM_NodeFilter::FILTER_ACCEPT;
  365.         }
  366.         else
  367.         {
  368.             return IDOM_NodeFilter::FILTER_SKIP;
  369.         }
  370.     } else {
  371.         // REVISIT: This logic is unclear from the spec!
  372.         if ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0 ) {
  373.             return fNodeFilter->acceptNode(node);
  374.         } else {
  375.             // what to show has failed!
  376.             if (fNodeFilter->acceptNode(node) == IDOM_NodeFilter::FILTER_REJECT) {
  377.                 return IDOM_NodeFilter::FILTER_REJECT;
  378.             } else {
  379.                 return IDOM_NodeFilter::FILTER_SKIP;
  380.             }
  381.         }
  382.     }
  383. }