source: icXML/icXML-devel/src/xercesc/dom/impl/DOMTreeWalkerImpl.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 11.5 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: DOMTreeWalkerImpl.cpp 671894 2008-06-26 13:29:21Z borisk $
20 */
21
22#include "DOMTreeWalkerImpl.hpp"
23#include "DOMDocumentImpl.hpp"
24
25#include <xercesc/dom/DOMDocument.hpp>
26#include <xercesc/dom/DOMException.hpp>
27
28XERCES_CPP_NAMESPACE_BEGIN
29
30/** constructor */
31DOMTreeWalkerImpl::DOMTreeWalkerImpl (
32                                DOMNode* root,
33                                DOMNodeFilter::ShowType whatToShow,
34                                DOMNodeFilter* nodeFilter,
35                                bool expandEntityRef)
36:   fWhatToShow(whatToShow),
37    fNodeFilter(nodeFilter),
38    fCurrentNode(root),
39    fRoot(root),
40    fExpandEntityReferences(expandEntityRef)
41{
42}
43
44
45DOMTreeWalkerImpl::DOMTreeWalkerImpl (const DOMTreeWalkerImpl& twi)
46:   DOMTreeWalker(twi),
47    fWhatToShow(twi.fWhatToShow),
48    fNodeFilter(twi.fNodeFilter),
49    fCurrentNode(twi.fCurrentNode),
50    fRoot(twi.fRoot),
51    fExpandEntityReferences(twi.fExpandEntityReferences)
52{
53}
54
55
56DOMTreeWalkerImpl& DOMTreeWalkerImpl::operator= (const DOMTreeWalkerImpl& twi) {
57    if (this != &twi)
58    {
59        fCurrentNode            = twi.fCurrentNode;
60        fRoot                   = twi.fRoot;
61        fWhatToShow             = twi.fWhatToShow;
62        fNodeFilter             = twi.fNodeFilter;
63                fExpandEntityReferences = twi.fExpandEntityReferences;
64    }
65
66    return *this;
67}
68
69
70
71/** Return the root node */
72DOMNode* DOMTreeWalkerImpl::getRoot () {
73    return fRoot;
74}
75
76
77/** Return the whatToShow value */
78DOMNodeFilter::ShowType DOMTreeWalkerImpl::getWhatToShow () {
79    return fWhatToShow;
80}
81
82
83/** Return the NodeFilter */
84DOMNodeFilter* DOMTreeWalkerImpl::getFilter () {
85    return fNodeFilter;
86}
87
88/** Get the expandEntity reference flag. */
89bool DOMTreeWalkerImpl::getExpandEntityReferences() {
90    return fExpandEntityReferences;
91}
92
93
94
95/** Return the current Node. */
96DOMNode* DOMTreeWalkerImpl::getCurrentNode () {
97
98    return fCurrentNode;
99}
100
101
102/** Return the current Node. */
103void DOMTreeWalkerImpl::setCurrentNode (DOMNode* node) {
104
105    if (!node)
106        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, GetDOMTreeWalkerMemoryManager);
107
108    fCurrentNode = node;
109}
110
111
112/** Return the parent Node from the current node,
113 *  after applying filter, whatToshow.
114 *  If result is not null, set the current Node.
115 */
116DOMNode* DOMTreeWalkerImpl::parentNode () {
117
118    if (!fCurrentNode) return 0;
119
120    DOMNode* node = getParentNode(fCurrentNode);
121    if (node != 0) {
122        fCurrentNode = node;
123    }
124    return node;
125
126}
127
128
129/** Return the first child Node from the current node,
130 *  after applying filter, whatToshow.
131 *  If result is not null, set the current Node.
132 */
133DOMNode* DOMTreeWalkerImpl::firstChild () {
134
135    if (!fCurrentNode) return 0;
136
137    if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
138        return 0;
139
140    DOMNode* node = getFirstChild(fCurrentNode);
141
142    if (node != 0) {
143        fCurrentNode = node;
144    }
145    return node;
146}
147
148
149/** Return the last child Node from the current node,
150 *  after applying filter, whatToshow.
151 *  If result is not null, set the current Node.
152 */
153DOMNode* DOMTreeWalkerImpl::lastChild () {
154
155    if (!fCurrentNode) return 0;
156
157    if(!fExpandEntityReferences && fCurrentNode->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
158        return 0;
159
160    DOMNode* node = getLastChild(fCurrentNode);
161    if (node != 0) {
162        fCurrentNode = node;
163    }
164    return node;
165}
166
167
168/** Return the previous sibling Node from the current node,
169 *  after applying filter, whatToshow.
170 *  If result is not null, set the current Node.
171 */
172
173DOMNode* DOMTreeWalkerImpl::previousSibling () {
174
175    if (!fCurrentNode) return 0;
176
177    DOMNode* node = getPreviousSibling(fCurrentNode);
178    if (node != 0) {
179        fCurrentNode = node;
180    }
181    return node;
182}
183
184
185/** Return the next sibling Node from the current node,
186 *  after applying filter, whatToshow.
187 *  If result is not null, set the current Node.
188 */
189
190DOMNode* DOMTreeWalkerImpl::nextSibling () {
191
192    if (!fCurrentNode) return 0;
193
194    DOMNode* node = getNextSibling(fCurrentNode);
195    if (node != 0) {
196        fCurrentNode = node;
197    }
198    return node;
199}
200
201
202/** Return the previous Node from the current node,
203 *  after applying filter, whatToshow.
204 *  If result is not null, set the current Node.
205 */
206
207DOMNode* DOMTreeWalkerImpl::previousNode () {
208
209    if (!fCurrentNode) return 0;
210
211    // get sibling
212    DOMNode* node = getPreviousSibling(fCurrentNode);
213    if (node == 0) {
214        node = getParentNode(fCurrentNode);
215        if ( node != 0) {
216            fCurrentNode = node;
217        }
218        return node;
219    }
220    else {
221
222        // get the lastChild of result.
223        DOMNode* lastChild  = getLastChild(node);
224
225        // if there is a lastChild which passes filters return it.
226        if (lastChild != 0) {
227            fCurrentNode = lastChild;
228        }
229        else {
230            fCurrentNode = node;
231        }
232        return fCurrentNode;
233    }
234}
235
236
237/** Return the next Node from the current node,
238 *  after applying filter, whatToshow.
239 *  If result is not null, set the current Node.
240 */
241
242DOMNode* DOMTreeWalkerImpl::nextNode () {
243
244    if (!fCurrentNode) return 0;
245
246    DOMNode* node = getFirstChild(fCurrentNode);
247
248    if (node != 0) {
249        fCurrentNode = node;
250        return node;
251    }
252    else {
253
254        node = getNextSibling(fCurrentNode);
255
256        if (node != 0) {
257            fCurrentNode = node;
258            return node;
259        }
260        else {
261
262            // return parent's 1st sibling.
263            DOMNode* parent = getParentNode(fCurrentNode);
264            while ( parent != 0) {
265                node = getNextSibling(parent);
266                if (node != 0) {
267                    fCurrentNode = node;
268                    return node;
269                } else {
270                    parent = getParentNode(parent);
271                }
272            }
273            return node;
274        }
275    }
276}
277
278
279/** Internal function.
280 *  Return the parent Node, from the input node
281 *  after applying filter, whatToshow.
282 *  The current node is not consulted or set.
283 */
284
285DOMNode* DOMTreeWalkerImpl::getParentNode (DOMNode* node) {
286
287    if (!node || node == fRoot) return 0;
288
289    DOMNode* newNode = node->getParentNode();
290    if (!newNode)  return 0;
291
292    short accept = acceptNode(newNode);
293
294    if (accept == DOMNodeFilter::FILTER_ACCEPT)
295        return newNode;
296
297    return getParentNode(newNode);
298
299}
300
301
302/** Internal function.
303 *  Return the nextSibling Node, from the input node
304 *  after applying filter, whatToshow.
305 *  The current node is not consulted or set.
306 */
307
308DOMNode* DOMTreeWalkerImpl::getNextSibling (DOMNode* node) {
309
310    if (!node || node == fRoot) return 0;
311
312    DOMNode* newNode = node->getNextSibling();
313    if (!newNode) {
314
315        newNode = node->getParentNode();
316
317        if (!newNode || node == fRoot)  return 0;
318
319        short parentAccept = acceptNode(newNode);
320
321        if (parentAccept == DOMNodeFilter::FILTER_SKIP) {
322            return getNextSibling(newNode);
323        }
324
325        return 0;
326    }
327
328    short accept = acceptNode(newNode);
329
330    if (accept == DOMNodeFilter::FILTER_ACCEPT)
331        return newNode;
332    else
333    if (accept == DOMNodeFilter::FILTER_SKIP) {
334        DOMNode* fChild =  getFirstChild(newNode);
335        if (!fChild && !newNode->hasChildNodes()) {
336            return getNextSibling(newNode);
337        }
338        return fChild;
339    }
340    return getNextSibling(newNode);
341
342}
343
344
345/** Internal function.
346 *  Return the previous sibling Node, from the input node
347 *  after applying filter, whatToshow.
348 *  The current node is not consulted or set.
349 */
350
351DOMNode* DOMTreeWalkerImpl::getPreviousSibling (DOMNode* node) {
352
353    if (!node || node == fRoot) return 0;
354
355    DOMNode* newNode = node->getPreviousSibling();
356    if (!newNode) {
357
358        newNode = node->getParentNode();
359        if (!newNode || node == fRoot)  return 0;
360
361        short parentAccept = acceptNode(newNode);
362
363        if (parentAccept == DOMNodeFilter::FILTER_SKIP) {
364            return getPreviousSibling(newNode);
365        }
366
367        return 0;
368    }
369
370    short accept = acceptNode(newNode);
371
372    if (accept == DOMNodeFilter::FILTER_ACCEPT)
373        return newNode;
374    else
375    if (accept == DOMNodeFilter::FILTER_SKIP) {
376        DOMNode* fChild =  getLastChild(newNode);
377        if (!fChild && !newNode->hasChildNodes()) {
378            return getPreviousSibling(newNode);
379        }
380        return fChild;
381    }
382    return getPreviousSibling(newNode);
383
384}
385
386
387/** Internal function.
388 *  Return the first child Node, from the input node
389 *  after applying filter, whatToshow.
390 *  The current node is not consulted or set.
391 */
392
393DOMNode* DOMTreeWalkerImpl::getFirstChild (DOMNode* node) {
394
395    if (!node) return 0;
396
397    if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
398        return 0;
399
400    DOMNode* newNode = node->getFirstChild();
401    if (!newNode)  return 0;
402
403    short accept = acceptNode(newNode);
404
405    if (accept == DOMNodeFilter::FILTER_ACCEPT)
406        return newNode;
407    else
408    if (accept == DOMNodeFilter::FILTER_SKIP
409        && newNode->hasChildNodes())
410    {
411        return getFirstChild(newNode);
412    }
413    return getNextSibling(newNode);
414
415}
416
417
418/** Internal function.
419 *  Return the last child Node, from the input node
420 *  after applying filter, whatToshow.
421 *  The current node is not consulted or set.
422 */
423
424DOMNode* DOMTreeWalkerImpl::getLastChild (DOMNode* node) {
425
426    if (!node) return 0;
427
428    if(!fExpandEntityReferences && node->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
429        return 0;
430
431    DOMNode* newNode = node->getLastChild();
432    if (!newNode)  return 0;
433
434    short accept = acceptNode(newNode);
435
436    if (accept == DOMNodeFilter::FILTER_ACCEPT)
437        return newNode;
438    else
439    if (accept == DOMNodeFilter::FILTER_SKIP
440        && newNode->hasChildNodes())
441    {
442        return getLastChild(newNode);
443    }
444    return getPreviousSibling(newNode);
445
446}
447
448
449/** The node is accepted if it passes the whatToShow and the filter. */
450
451short DOMTreeWalkerImpl::acceptNode (DOMNode* node) {
452
453    if (fNodeFilter == 0) {
454        if ( ( fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)
455        {
456            return DOMNodeFilter::FILTER_ACCEPT;
457        }
458        else
459        {
460            return DOMNodeFilter::FILTER_SKIP;
461        }
462    } else {
463        // REVISIT: This logic is unclear from the spec!
464        if ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0 ) {
465            return fNodeFilter->acceptNode(node);
466        } else {
467            // what to show has failed!
468            if (fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_REJECT) {
469                return DOMNodeFilter::FILTER_REJECT;
470            } else {
471                return DOMNodeFilter::FILTER_SKIP;
472            }
473        }
474    }
475}
476
477
478void DOMTreeWalkerImpl::release()
479{
480    // for performance reason, do not recycle pointer
481    // chance that this is allocated again and again is not usual
482}
483
484XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.