GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: DOMTreeWalkerImpl.cpp 671894 2008-06-26 13:29:21Z borisk $ 00020 */ 00021 00022 #include "DOMTreeWalkerImpl.hpp" 00023 #include "DOMDocumentImpl.hpp" 00024 00025 #include <xercesc/dom/DOMDocument.hpp> 00026 #include <xercesc/dom/DOMException.hpp> 00027 00028 XERCES_CPP_NAMESPACE_BEGIN 00029 00031 DOMTreeWalkerImpl::DOMTreeWalkerImpl ( 00032 DOMNode* root, 00033 DOMNodeFilter::ShowType whatToShow, 00034 DOMNodeFilter* nodeFilter, 00035 bool expandEntityRef) 00036 : fWhatToShow(whatToShow), 00037 fNodeFilter(nodeFilter), 00038 fCurrentNode(root), 00039 fRoot(root), 00040 fExpandEntityReferences(expandEntityRef) 00041 { 00042 } 00043 00044 00045 DOMTreeWalkerImpl::DOMTreeWalkerImpl (const DOMTreeWalkerImpl& twi) 00046 : DOMTreeWalker(twi), 00047 fWhatToShow(twi.fWhatToShow), 00048 fNodeFilter(twi.fNodeFilter), 00049 fCurrentNode(twi.fCurrentNode), 00050 fRoot(twi.fRoot), 00051 fExpandEntityReferences(twi.fExpandEntityReferences) 00052 { 00053 } 00054 00055 00056 DOMTreeWalkerImpl& DOMTreeWalkerImpl::operator= (const DOMTreeWalkerImpl& twi) { 00057 if (this != &twi) 00058 { 00059 fCurrentNode = twi.fCurrentNode; 00060 fRoot = twi.fRoot; 00061 fWhatToShow = twi.fWhatToShow; 00062 fNodeFilter = twi.fNodeFilter; 00063 fExpandEntityReferences = twi.fExpandEntityReferences; 00064 } 00065 00066 return *this; 00067 } 00068 00069 00070 00072 DOMNode* DOMTreeWalkerImpl::getRoot () { 00073 return fRoot; 00074 } 00075 00076 00078 DOMNodeFilter::ShowType DOMTreeWalkerImpl::getWhatToShow () { 00079 return fWhatToShow; 00080 } 00081 00082 00084 DOMNodeFilter* DOMTreeWalkerImpl::getFilter () { 00085 return fNodeFilter; 00086 } 00087 00089 bool DOMTreeWalkerImpl::getExpandEntityReferences() { 00090 return fExpandEntityReferences; 00091 } 00092 00093 00094 00096 DOMNode* DOMTreeWalkerImpl::getCurrentNode () { 00097 00098 return fCurrentNode; 00099 } 00100 00101 00103 void DOMTreeWalkerImpl::setCurrentNode (DOMNode* node) { 00104 00105 if (!node) 00106 throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMTreeWalkerMemoryManager); 00107 00108 fCurrentNode = node; 00109 } 00110 00111 00116 DOMNode* DOMTreeWalkerImpl::parentNode () { 00117 00118 if (!fCurrentNode) return 0; 00119 00120 DOMNode* node = getParentNode(fCurrentNode); 00121 if (node != 0) { 00122 fCurrentNode = node; 00123 } 00124 return node; 00125 00126 } 00127 00128 00133 DOMNode* DOMTreeWalkerImpl::firstChild () { 00134 00135 if (!fCurrentNode) return 0; 00136 00137 if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE) 00138 return 0; 00139 00140 DOMNode* node = getFirstChild(fCurrentNode); 00141 00142 if (node != 0) { 00143 fCurrentNode = node; 00144 } 00145 return node; 00146 } 00147 00148 00153 DOMNode* DOMTreeWalkerImpl::lastChild () { 00154 00155 if (!fCurrentNode) return 0; 00156 00157 if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE) 00158 return 0; 00159 00160 DOMNode* node = getLastChild(fCurrentNode); 00161 if (node != 0) { 00162 fCurrentNode = node; 00163 } 00164 return node; 00165 } 00166 00167 00173 DOMNode* DOMTreeWalkerImpl::previousSibling () { 00174 00175 if (!fCurrentNode) return 0; 00176 00177 DOMNode* node = getPreviousSibling(fCurrentNode); 00178 if (node != 0) { 00179 fCurrentNode = node; 00180 } 00181 return node; 00182 } 00183 00184 00190 DOMNode* DOMTreeWalkerImpl::nextSibling () { 00191 00192 if (!fCurrentNode) return 0; 00193 00194 DOMNode* node = getNextSibling(fCurrentNode); 00195 if (node != 0) { 00196 fCurrentNode = node; 00197 } 00198 return node; 00199 } 00200 00201 00207 DOMNode* DOMTreeWalkerImpl::previousNode () { 00208 00209 if (!fCurrentNode) return 0; 00210 00211 // get sibling 00212 DOMNode* node = getPreviousSibling(fCurrentNode); 00213 if (node == 0) { 00214 node = getParentNode(fCurrentNode); 00215 if ( node != 0) { 00216 fCurrentNode = node; 00217 } 00218 return node; 00219 } 00220 else { 00221 00222 // get the lastChild of result. 00223 DOMNode* lastChild = getLastChild(node); 00224 00225 // if there is a lastChild which passes filters return it. 00226 if (lastChild != 0) { 00227 fCurrentNode = lastChild; 00228 } 00229 else { 00230 fCurrentNode = node; 00231 } 00232 return fCurrentNode; 00233 } 00234 } 00235 00236 00242 DOMNode* DOMTreeWalkerImpl::nextNode () { 00243 00244 if (!fCurrentNode) return 0; 00245 00246 DOMNode* node = getFirstChild(fCurrentNode); 00247 00248 if (node != 0) { 00249 fCurrentNode = node; 00250 return node; 00251 } 00252 else { 00253 00254 node = getNextSibling(fCurrentNode); 00255 00256 if (node != 0) { 00257 fCurrentNode = node; 00258 return node; 00259 } 00260 else { 00261 00262 // return parent's 1st sibling. 00263 DOMNode* parent = getParentNode(fCurrentNode); 00264 while ( parent != 0) { 00265 node = getNextSibling(parent); 00266 if (node != 0) { 00267 fCurrentNode = node; 00268 return node; 00269 } else { 00270 parent = getParentNode(parent); 00271 } 00272 } 00273 return node; 00274 } 00275 } 00276 } 00277 00278 00285 DOMNode* DOMTreeWalkerImpl::getParentNode (DOMNode* node) { 00286 00287 if (!node || node == fRoot) return 0; 00288 00289 DOMNode* newNode = node->getParentNode(); 00290 if (!newNode) return 0; 00291 00292 short accept = acceptNode(newNode); 00293 00294 if (accept == DOMNodeFilter::FILTER_ACCEPT) 00295 return newNode; 00296 00297 return getParentNode(newNode); 00298 00299 } 00300 00301 00308 DOMNode* DOMTreeWalkerImpl::getNextSibling (DOMNode* node) { 00309 00310 if (!node || node == fRoot) return 0; 00311 00312 DOMNode* newNode = node->getNextSibling(); 00313 if (!newNode) { 00314 00315 newNode = node->getParentNode(); 00316 00317 if (!newNode || node == fRoot) return 0; 00318 00319 short parentAccept = acceptNode(newNode); 00320 00321 if (parentAccept == DOMNodeFilter::FILTER_SKIP) { 00322 return getNextSibling(newNode); 00323 } 00324 00325 return 0; 00326 } 00327 00328 short accept = acceptNode(newNode); 00329 00330 if (accept == DOMNodeFilter::FILTER_ACCEPT) 00331 return newNode; 00332 else 00333 if (accept == DOMNodeFilter::FILTER_SKIP) { 00334 DOMNode* fChild = getFirstChild(newNode); 00335 if (!fChild && !newNode->hasChildNodes()) { 00336 return getNextSibling(newNode); 00337 } 00338 return fChild; 00339 } 00340 return getNextSibling(newNode); 00341 00342 } 00343 00344 00351 DOMNode* DOMTreeWalkerImpl::getPreviousSibling (DOMNode* node) { 00352 00353 if (!node || node == fRoot) return 0; 00354 00355 DOMNode* newNode = node->getPreviousSibling(); 00356 if (!newNode) { 00357 00358 newNode = node->getParentNode(); 00359 if (!newNode || node == fRoot) return 0; 00360 00361 short parentAccept = acceptNode(newNode); 00362 00363 if (parentAccept == DOMNodeFilter::FILTER_SKIP) { 00364 return getPreviousSibling(newNode); 00365 } 00366 00367 return 0; 00368 } 00369 00370 short accept = acceptNode(newNode); 00371 00372 if (accept == DOMNodeFilter::FILTER_ACCEPT) 00373 return newNode; 00374 else 00375 if (accept == DOMNodeFilter::FILTER_SKIP) { 00376 DOMNode* fChild = getLastChild(newNode); 00377 if (!fChild && !newNode->hasChildNodes()) { 00378 return getPreviousSibling(newNode); 00379 } 00380 return fChild; 00381 } 00382 return getPreviousSibling(newNode); 00383 00384 } 00385 00386 00393 DOMNode* DOMTreeWalkerImpl::getFirstChild (DOMNode* node) { 00394 00395 if (!node) return 0; 00396 00397 if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE) 00398 return 0; 00399 00400 DOMNode* newNode = node->getFirstChild(); 00401 if (!newNode) return 0; 00402 00403 short accept = acceptNode(newNode); 00404 00405 if (accept == DOMNodeFilter::FILTER_ACCEPT) 00406 return newNode; 00407 else 00408 if (accept == DOMNodeFilter::FILTER_SKIP 00409 && newNode->hasChildNodes()) 00410 { 00411 return getFirstChild(newNode); 00412 } 00413 return getNextSibling(newNode); 00414 00415 } 00416 00417 00424 DOMNode* DOMTreeWalkerImpl::getLastChild (DOMNode* node) { 00425 00426 if (!node) return 0; 00427 00428 if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE) 00429 return 0; 00430 00431 DOMNode* newNode = node->getLastChild(); 00432 if (!newNode) return 0; 00433 00434 short accept = acceptNode(newNode); 00435 00436 if (accept == DOMNodeFilter::FILTER_ACCEPT) 00437 return newNode; 00438 else 00439 if (accept == DOMNodeFilter::FILTER_SKIP 00440 && newNode->hasChildNodes()) 00441 { 00442 return getLastChild(newNode); 00443 } 00444 return getPreviousSibling(newNode); 00445 00446 } 00447 00448 00451 short DOMTreeWalkerImpl::acceptNode (DOMNode* node) { 00452 00453 if (fNodeFilter == 0) { 00454 if ( ( fWhatToShow & (1 << (node->getNodeType() - 1))) != 0) 00455 { 00456 return DOMNodeFilter::FILTER_ACCEPT; 00457 } 00458 else 00459 { 00460 return DOMNodeFilter::FILTER_SKIP; 00461 } 00462 } else { 00463 // REVISIT: This logic is unclear from the spec! 00464 if ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0 ) { 00465 return fNodeFilter->acceptNode(node); 00466 } else { 00467 // what to show has failed! 00468 if (fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_REJECT) { 00469 return DOMNodeFilter::FILTER_REJECT; 00470 } else { 00471 return DOMNodeFilter::FILTER_SKIP; 00472 } 00473 } 00474 } 00475 } 00476 00477 00478 void DOMTreeWalkerImpl::release() 00479 { 00480 // for performance reason, do not recycle pointer 00481 // chance that this is allocated again and again is not usual 00482 } 00483 00484 XERCES_CPP_NAMESPACE_END