Source Code Cross Referenced for DTMDefaultBaseIterators.java in  » XML » xalan » org » apache » xml » dtm » ref » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xalan » org.apache.xml.dtm.ref 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2004 The Apache Software Foundation.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *     http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        /*
0017:         * $Id: DTMDefaultBaseIterators.java,v 1.23 2005/01/24 00:34:35 mcnamara Exp $
0018:         */
0019:        package org.apache.xml.dtm.ref;
0020:
0021:        import org.apache.xml.dtm.*;
0022:
0023:        import javax.xml.transform.Source;
0024:
0025:        import org.apache.xml.utils.XMLStringFactory;
0026:
0027:        import org.apache.xml.res.XMLErrorResources;
0028:        import org.apache.xml.res.XMLMessages;
0029:        import org.apache.xalan.xsltc.dom.NodeCounter;
0030:
0031:        /**
0032:         * This class implements the traversers for DTMDefaultBase.
0033:         */
0034:        public abstract class DTMDefaultBaseIterators extends
0035:                DTMDefaultBaseTraversers {
0036:
0037:            /**
0038:             * Construct a DTMDefaultBaseTraversers object from a DOM node.
0039:             *
0040:             * @param mgr The DTMManager who owns this DTM.
0041:             * @param source The object that is used to specify the construction source.
0042:             * @param dtmIdentity The DTM identity ID for this DTM.
0043:             * @param whiteSpaceFilter The white space filter for this DTM, which may
0044:             *                         be null.
0045:             * @param xstringfactory The factory to use for creating XMLStrings.
0046:             * @param doIndexing true if the caller considers it worth it to use 
0047:             *                   indexing schemes.
0048:             */
0049:            public DTMDefaultBaseIterators(DTMManager mgr, Source source,
0050:                    int dtmIdentity, DTMWSFilter whiteSpaceFilter,
0051:                    XMLStringFactory xstringfactory, boolean doIndexing) {
0052:                super (mgr, source, dtmIdentity, whiteSpaceFilter,
0053:                        xstringfactory, doIndexing);
0054:            }
0055:
0056:            /**
0057:             * Construct a DTMDefaultBaseTraversers object from a DOM node.
0058:             *
0059:             * @param mgr The DTMManager who owns this DTM.
0060:             * @param source The object that is used to specify the construction source.
0061:             * @param dtmIdentity The DTM identity ID for this DTM.
0062:             * @param whiteSpaceFilter The white space filter for this DTM, which may
0063:             *                         be null.
0064:             * @param xstringfactory The factory to use for creating XMLStrings.
0065:             * @param doIndexing true if the caller considers it worth it to use 
0066:             *                   indexing schemes.
0067:             * @param blocksize The block size of the DTM.
0068:             * @param usePrevsib true if we want to build the previous sibling node array.
0069:             * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
0070:             */
0071:            public DTMDefaultBaseIterators(DTMManager mgr, Source source,
0072:                    int dtmIdentity, DTMWSFilter whiteSpaceFilter,
0073:                    XMLStringFactory xstringfactory, boolean doIndexing,
0074:                    int blocksize, boolean usePrevsib, boolean newNameTable) {
0075:                super (mgr, source, dtmIdentity, whiteSpaceFilter,
0076:                        xstringfactory, doIndexing, blocksize, usePrevsib,
0077:                        newNameTable);
0078:            }
0079:
0080:            /**
0081:             * Get an iterator that can navigate over an XPath Axis, predicated by
0082:             * the extended type ID.
0083:             * Returns an iterator that must be initialized
0084:             * with a start node (using iterator.setStartNode()).
0085:             *
0086:             * @param axis One of Axes.ANCESTORORSELF, etc.
0087:             * @param type An extended type ID.
0088:             *
0089:             * @return A DTMAxisIterator, or null if the given axis isn't supported.
0090:             */
0091:            public DTMAxisIterator getTypedAxisIterator(int axis, int type) {
0092:
0093:                DTMAxisIterator iterator = null;
0094:
0095:                /* This causes an error when using patterns for elements that
0096:                   do not exist in the DOM (translet types which do not correspond
0097:                   to a DOM type are mapped to the DOM.ELEMENT type).
0098:                 */
0099:
0100:                //        if (type == NO_TYPE) {
0101:                //            return(EMPTYITERATOR);
0102:                //        }
0103:                //        else if (type == ELEMENT) {
0104:                //            iterator = new FilterIterator(getAxisIterator(axis),
0105:                //                                          getElementFilter());
0106:                //        }
0107:                //        else 
0108:                {
0109:                    switch (axis) {
0110:                    case Axis.SELF:
0111:                        iterator = new TypedSingletonIterator(type);
0112:                        break;
0113:                    case Axis.CHILD:
0114:                        iterator = new TypedChildrenIterator(type);
0115:                        break;
0116:                    case Axis.PARENT:
0117:                        return (new ParentIterator().setNodeType(type));
0118:                    case Axis.ANCESTOR:
0119:                        return (new TypedAncestorIterator(type));
0120:                    case Axis.ANCESTORORSELF:
0121:                        return ((new TypedAncestorIterator(type)).includeSelf());
0122:                    case Axis.ATTRIBUTE:
0123:                        return (new TypedAttributeIterator(type));
0124:                    case Axis.DESCENDANT:
0125:                        iterator = new TypedDescendantIterator(type);
0126:                        break;
0127:                    case Axis.DESCENDANTORSELF:
0128:                        iterator = (new TypedDescendantIterator(type))
0129:                                .includeSelf();
0130:                        break;
0131:                    case Axis.FOLLOWING:
0132:                        iterator = new TypedFollowingIterator(type);
0133:                        break;
0134:                    case Axis.PRECEDING:
0135:                        iterator = new TypedPrecedingIterator(type);
0136:                        break;
0137:                    case Axis.FOLLOWINGSIBLING:
0138:                        iterator = new TypedFollowingSiblingIterator(type);
0139:                        break;
0140:                    case Axis.PRECEDINGSIBLING:
0141:                        iterator = new TypedPrecedingSiblingIterator(type);
0142:                        break;
0143:                    case Axis.NAMESPACE:
0144:                        iterator = new TypedNamespaceIterator(type);
0145:                        break;
0146:                    case Axis.ROOT:
0147:                        iterator = new TypedRootIterator(type);
0148:                        break;
0149:                    default:
0150:                        throw new DTMException(
0151:                                XMLMessages
0152:                                        .createXMLMessage(
0153:                                                XMLErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED,
0154:                                                new Object[] { Axis
0155:                                                        .getNames(axis) }));
0156:                        //"Error: typed iterator for axis "
0157:                        //+ Axis.names[axis] + "not implemented");
0158:                    }
0159:                }
0160:
0161:                return (iterator);
0162:            }
0163:
0164:            /**
0165:             * This is a shortcut to the iterators that implement the
0166:             * XPath axes.
0167:             * Returns a bare-bones iterator that must be initialized
0168:             * with a start node (using iterator.setStartNode()).
0169:             *
0170:             * @param axis One of Axes.ANCESTORORSELF, etc.
0171:             *
0172:             * @return A DTMAxisIterator, or null if the given axis isn't supported.
0173:             */
0174:            public DTMAxisIterator getAxisIterator(final int axis) {
0175:
0176:                DTMAxisIterator iterator = null;
0177:
0178:                switch (axis) {
0179:                case Axis.SELF:
0180:                    iterator = new SingletonIterator();
0181:                    break;
0182:                case Axis.CHILD:
0183:                    iterator = new ChildrenIterator();
0184:                    break;
0185:                case Axis.PARENT:
0186:                    return (new ParentIterator());
0187:                case Axis.ANCESTOR:
0188:                    return (new AncestorIterator());
0189:                case Axis.ANCESTORORSELF:
0190:                    return ((new AncestorIterator()).includeSelf());
0191:                case Axis.ATTRIBUTE:
0192:                    return (new AttributeIterator());
0193:                case Axis.DESCENDANT:
0194:                    iterator = new DescendantIterator();
0195:                    break;
0196:                case Axis.DESCENDANTORSELF:
0197:                    iterator = (new DescendantIterator()).includeSelf();
0198:                    break;
0199:                case Axis.FOLLOWING:
0200:                    iterator = new FollowingIterator();
0201:                    break;
0202:                case Axis.PRECEDING:
0203:                    iterator = new PrecedingIterator();
0204:                    break;
0205:                case Axis.FOLLOWINGSIBLING:
0206:                    iterator = new FollowingSiblingIterator();
0207:                    break;
0208:                case Axis.PRECEDINGSIBLING:
0209:                    iterator = new PrecedingSiblingIterator();
0210:                    break;
0211:                case Axis.NAMESPACE:
0212:                    iterator = new NamespaceIterator();
0213:                    break;
0214:                case Axis.ROOT:
0215:                    iterator = new RootIterator();
0216:                    break;
0217:                default:
0218:                    throw new DTMException(XMLMessages.createXMLMessage(
0219:                            XMLErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED,
0220:                            new Object[] { Axis.getNames(axis) }));
0221:                    //"Error: iterator for axis '" + Axis.names[axis]
0222:                    //+ "' not implemented");
0223:                }
0224:
0225:                return (iterator);
0226:            }
0227:
0228:            /**
0229:             * Abstract superclass defining behaviors shared by all DTMDefault's
0230:             * internal implementations of DTMAxisIterator. Subclass this (and
0231:             * override, if necessary) to implement the specifics of an
0232:             * individual axis iterator.
0233:             *
0234:             * Currently there isn't a lot here
0235:             */
0236:            public abstract class InternalAxisIteratorBase extends
0237:                    DTMAxisIteratorBase {
0238:
0239:                // %REVIEW% We could opt to share _nodeType and setNodeType() as
0240:                // well, and simply ignore them in iterators which don't use them.
0241:                // But Scott's worried about the overhead involved in cloning
0242:                // these, and wants them to have as few fields as possible. Note
0243:                // that we can't create a TypedInternalAxisIteratorBase because
0244:                // those are often based on the untyped versions and Java doesn't
0245:                // support multiple inheritance. <sigh/>
0246:
0247:                /**
0248:                 * Current iteration location. Usually this is the last location
0249:                 * returned (starting point for the next() search); for single-node
0250:                 * iterators it may instead be initialized to point to that single node.
0251:                 */
0252:                protected int _currentNode;
0253:
0254:                /**
0255:                 * Remembers the current node for the next call to gotoMark().
0256:                 *
0257:                 * %REVIEW% Should this save _position too?
0258:                 */
0259:                public void setMark() {
0260:                    _markedNode = _currentNode;
0261:                }
0262:
0263:                /**
0264:                 * Restores the current node remembered by setMark().
0265:                 *
0266:                 * %REVEIW% Should this restore _position too?
0267:                 */
0268:                public void gotoMark() {
0269:                    _currentNode = _markedNode;
0270:                }
0271:
0272:            } // end of InternalAxisIteratorBase 
0273:
0274:            /**
0275:             * Iterator that returns all immediate children of a given node
0276:             */
0277:            public final class ChildrenIterator extends
0278:                    InternalAxisIteratorBase {
0279:
0280:                /**
0281:                 * Setting start to END should 'close' the iterator,
0282:                 * i.e. subsequent call to next() should return END.
0283:                 *
0284:                 * If the iterator is not restartable, this has no effect.
0285:                 * %REVIEW% Should it return/throw something in that case,
0286:                 * or set current node to END, to indicate request-not-honored?
0287:                 *
0288:                 * @param node Sets the root of the iteration.
0289:                 *
0290:                 * @return A DTMAxisIterator set to the start of the iteration.
0291:                 */
0292:                public DTMAxisIterator setStartNode(int node) {
0293:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0294:                    if (node == DTMDefaultBase.ROOTNODE)
0295:                        node = getDocument();
0296:                    if (_isRestartable) {
0297:                        _startNode = node;
0298:                        _currentNode = (node == DTM.NULL) ? DTM.NULL
0299:                                : _firstch(makeNodeIdentity(node));
0300:
0301:                        return resetPosition();
0302:                    }
0303:
0304:                    return this ;
0305:                }
0306:
0307:                /**
0308:                 * Get the next node in the iteration.
0309:                 *
0310:                 * @return The next node handle in the iteration, or END if no more
0311:                 * are available.
0312:                 */
0313:                public int next() {
0314:                    if (_currentNode != NULL) {
0315:                        int node = _currentNode;
0316:                        _currentNode = _nextsib(node);
0317:                        return returnNode(makeNodeHandle(node));
0318:                    }
0319:
0320:                    return END;
0321:                }
0322:            } // end of ChildrenIterator
0323:
0324:            /**
0325:             * Iterator that returns the parent of a given node. Note that
0326:             * this delivers only a single node; if you want all the ancestors,
0327:             * see AncestorIterator.
0328:             */
0329:            public final class ParentIterator extends InternalAxisIteratorBase {
0330:
0331:                /** The extended type ID that was requested. */
0332:                private int _nodeType = -1;
0333:
0334:                /**
0335:                 * Set start to END should 'close' the iterator,
0336:                 * i.e. subsequent call to next() should return END.
0337:                 *
0338:                 * @param node Sets the root of the iteration.
0339:                 *
0340:                 * @return A DTMAxisIterator set to the start of the iteration.
0341:                 */
0342:                public DTMAxisIterator setStartNode(int node) {
0343:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0344:                    if (node == DTMDefaultBase.ROOTNODE)
0345:                        node = getDocument();
0346:                    if (_isRestartable) {
0347:                        _startNode = node;
0348:                        _currentNode = getParent(node);
0349:
0350:                        return resetPosition();
0351:                    }
0352:
0353:                    return this ;
0354:                }
0355:
0356:                /**
0357:                 * Set the node type of the parent that we're looking for.
0358:                 * Note that this does _not_ mean "find the nearest ancestor of
0359:                 * this type", but "yield the parent if it is of this type".
0360:                 *
0361:                 *
0362:                 * @param type extended type ID.
0363:                 *
0364:                 * @return ParentIterator configured with the type filter set.
0365:                 */
0366:                public DTMAxisIterator setNodeType(final int type) {
0367:
0368:                    _nodeType = type;
0369:
0370:                    return this ;
0371:                }
0372:
0373:                /**
0374:                 * Get the next node in the iteration. In this case, we return
0375:                 * only the immediate parent, _if_ it matches the requested nodeType.
0376:                 *
0377:                 * @return The next node handle in the iteration, or END.
0378:                 */
0379:                public int next() {
0380:                    int result = _currentNode;
0381:
0382:                    if (_nodeType >= DTM.NTYPES) {
0383:                        if (_nodeType != getExpandedTypeID(_currentNode)) {
0384:                            result = END;
0385:                        }
0386:                    } else if (_nodeType != NULL) {
0387:                        if (_nodeType != getNodeType(_currentNode)) {
0388:                            result = END;
0389:                        }
0390:                    }
0391:
0392:                    _currentNode = END;
0393:
0394:                    return returnNode(result);
0395:                }
0396:            } // end of ParentIterator
0397:
0398:            /**
0399:             * Iterator that returns children of a given type for a given node.
0400:             * The functionality chould be achieved by putting a filter on top
0401:             * of a basic child iterator, but a specialised iterator is used
0402:             * for efficiency (both speed and size of translet).
0403:             */
0404:            public final class TypedChildrenIterator extends
0405:                    InternalAxisIteratorBase {
0406:
0407:                /** The extended type ID that was requested. */
0408:                private final int _nodeType;
0409:
0410:                /**
0411:                 * Constructor TypedChildrenIterator
0412:                 *
0413:                 *
0414:                 * @param nodeType The extended type ID being requested.
0415:                 */
0416:                public TypedChildrenIterator(int nodeType) {
0417:                    _nodeType = nodeType;
0418:                }
0419:
0420:                /**
0421:                 * Set start to END should 'close' the iterator,
0422:                 * i.e. subsequent call to next() should return END.
0423:                 *
0424:                 * @param node Sets the root of the iteration.
0425:                 *
0426:                 * @return A DTMAxisIterator set to the start of the iteration.
0427:                 */
0428:                public DTMAxisIterator setStartNode(int node) {
0429:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0430:                    if (node == DTMDefaultBase.ROOTNODE)
0431:                        node = getDocument();
0432:                    if (_isRestartable) {
0433:                        _startNode = node;
0434:                        _currentNode = (node == DTM.NULL) ? DTM.NULL
0435:                                : _firstch(makeNodeIdentity(_startNode));
0436:
0437:                        return resetPosition();
0438:                    }
0439:
0440:                    return this ;
0441:                }
0442:
0443:                /**
0444:                 * Get the next node in the iteration.
0445:                 *
0446:                 * @return The next node handle in the iteration, or END.
0447:                 */
0448:                public int next() {
0449:                    int eType;
0450:                    int node = _currentNode;
0451:
0452:                    int nodeType = _nodeType;
0453:
0454:                    if (nodeType >= DTM.NTYPES) {
0455:                        while (node != DTM.NULL && _exptype(node) != nodeType) {
0456:                            node = _nextsib(node);
0457:                        }
0458:                    } else {
0459:                        while (node != DTM.NULL) {
0460:                            eType = _exptype(node);
0461:                            if (eType < DTM.NTYPES) {
0462:                                if (eType == nodeType) {
0463:                                    break;
0464:                                }
0465:                            } else if (m_expandedNameTable.getType(eType) == nodeType) {
0466:                                break;
0467:                            }
0468:                            node = _nextsib(node);
0469:                        }
0470:                    }
0471:
0472:                    if (node == DTM.NULL) {
0473:                        _currentNode = DTM.NULL;
0474:                        return DTM.NULL;
0475:                    } else {
0476:                        _currentNode = _nextsib(node);
0477:                        return returnNode(makeNodeHandle(node));
0478:                    }
0479:
0480:                }
0481:            } // end of TypedChildrenIterator
0482:
0483:            /**
0484:             * Iterator that returns children within a given namespace for a
0485:             * given node. The functionality chould be achieved by putting a
0486:             * filter on top of a basic child iterator, but a specialised
0487:             * iterator is used for efficiency (both speed and size of translet).
0488:             */
0489:            public final class NamespaceChildrenIterator extends
0490:                    InternalAxisIteratorBase {
0491:
0492:                /** The extended type ID being requested. */
0493:                private final int _nsType;
0494:
0495:                /**
0496:                 * Constructor NamespaceChildrenIterator
0497:                 *
0498:                 *
0499:                 * @param type The extended type ID being requested.
0500:                 */
0501:                public NamespaceChildrenIterator(final int type) {
0502:                    _nsType = type;
0503:                }
0504:
0505:                /**
0506:                 * Set start to END should 'close' the iterator,
0507:                 * i.e. subsequent call to next() should return END.
0508:                 *
0509:                 * @param node Sets the root of the iteration.
0510:                 *
0511:                 * @return A DTMAxisIterator set to the start of the iteration.
0512:                 */
0513:                public DTMAxisIterator setStartNode(int node) {
0514:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0515:                    if (node == DTMDefaultBase.ROOTNODE)
0516:                        node = getDocument();
0517:                    if (_isRestartable) {
0518:                        _startNode = node;
0519:                        _currentNode = (node == DTM.NULL) ? DTM.NULL
0520:                                : NOTPROCESSED;
0521:
0522:                        return resetPosition();
0523:                    }
0524:
0525:                    return this ;
0526:                }
0527:
0528:                /**
0529:                 * Get the next node in the iteration.
0530:                 *
0531:                 * @return The next node handle in the iteration, or END.
0532:                 */
0533:                public int next() {
0534:                    if (_currentNode != DTM.NULL) {
0535:                        for (int node = (NOTPROCESSED == _currentNode) ? _firstch(makeNodeIdentity(_startNode))
0536:                                : _nextsib(_currentNode); node != END; node = _nextsib(node)) {
0537:                            if (m_expandedNameTable
0538:                                    .getNamespaceID(_exptype(node)) == _nsType) {
0539:                                _currentNode = node;
0540:
0541:                                return returnNode(node);
0542:                            }
0543:                        }
0544:                    }
0545:
0546:                    return END;
0547:                }
0548:            } // end of NamespaceChildrenIterator
0549:
0550:            /**
0551:             * Iterator that returns the namespace nodes as defined by the XPath data model 
0552:             * for a given node.
0553:             */
0554:            public class NamespaceIterator extends InternalAxisIteratorBase {
0555:
0556:                /**
0557:                 * Constructor NamespaceAttributeIterator
0558:                 */
0559:                public NamespaceIterator() {
0560:
0561:                    super ();
0562:                }
0563:
0564:                /**
0565:                 * Set start to END should 'close' the iterator,
0566:                 * i.e. subsequent call to next() should return END.
0567:                 *
0568:                 * @param node Sets the root of the iteration.
0569:                 *
0570:                 * @return A DTMAxisIterator set to the start of the iteration.
0571:                 */
0572:                public DTMAxisIterator setStartNode(int node) {
0573:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0574:                    if (node == DTMDefaultBase.ROOTNODE)
0575:                        node = getDocument();
0576:                    if (_isRestartable) {
0577:                        _startNode = node;
0578:                        _currentNode = getFirstNamespaceNode(node, true);
0579:
0580:                        return resetPosition();
0581:                    }
0582:
0583:                    return this ;
0584:                }
0585:
0586:                /**
0587:                 * Get the next node in the iteration.
0588:                 *
0589:                 * @return The next node handle in the iteration, or END.
0590:                 */
0591:                public int next() {
0592:
0593:                    int node = _currentNode;
0594:
0595:                    if (DTM.NULL != node)
0596:                        _currentNode = getNextNamespaceNode(_startNode, node,
0597:                                true);
0598:
0599:                    return returnNode(node);
0600:                }
0601:            } // end of NamespaceIterator
0602:
0603:            /**
0604:             * Iterator that returns the namespace nodes as defined by the XPath data model 
0605:             * for a given node, filtered by extended type ID.
0606:             */
0607:            public class TypedNamespaceIterator extends NamespaceIterator {
0608:
0609:                /** The extended type ID that was requested. */
0610:                private final int _nodeType;
0611:
0612:                /**
0613:                 * Constructor TypedNamespaceIterator
0614:                 *
0615:                 *
0616:                 * @param nodeType The extended type ID being requested.
0617:                 */
0618:                public TypedNamespaceIterator(int nodeType) {
0619:                    super ();
0620:                    _nodeType = nodeType;
0621:                }
0622:
0623:                /**
0624:                 * Get the next node in the iteration.
0625:                 *
0626:                 * @return The next node handle in the iteration, or END.
0627:                 */
0628:                public int next() {
0629:                    int node;
0630:
0631:                    for (node = _currentNode; node != END; node = getNextNamespaceNode(
0632:                            _startNode, node, true)) {
0633:                        if (getExpandedTypeID(node) == _nodeType
0634:                                || getNodeType(node) == _nodeType
0635:                                || getNamespaceType(node) == _nodeType) {
0636:                            _currentNode = node;
0637:
0638:                            return returnNode(node);
0639:                        }
0640:                    }
0641:
0642:                    return (_currentNode = END);
0643:                }
0644:            } // end of TypedNamespaceIterator
0645:
0646:            /**
0647:             * Iterator that returns the the root node as defined by the XPath data model 
0648:             * for a given node.
0649:             */
0650:            public class RootIterator extends InternalAxisIteratorBase {
0651:
0652:                /**
0653:                 * Constructor RootIterator
0654:                 */
0655:                public RootIterator() {
0656:
0657:                    super ();
0658:                }
0659:
0660:                /**
0661:                 * Set start to END should 'close' the iterator,
0662:                 * i.e. subsequent call to next() should return END.
0663:                 *
0664:                 * @param node Sets the root of the iteration.
0665:                 *
0666:                 * @return A DTMAxisIterator set to the start of the iteration.
0667:                 */
0668:                public DTMAxisIterator setStartNode(int node) {
0669:
0670:                    if (_isRestartable) {
0671:                        _startNode = getDocumentRoot(node);
0672:                        _currentNode = NULL;
0673:
0674:                        return resetPosition();
0675:                    }
0676:
0677:                    return this ;
0678:                }
0679:
0680:                /**
0681:                 * Get the next node in the iteration.
0682:                 *
0683:                 * @return The next node handle in the iteration, or END.
0684:                 */
0685:                public int next() {
0686:                    if (_startNode == _currentNode)
0687:                        return NULL;
0688:
0689:                    _currentNode = _startNode;
0690:
0691:                    return returnNode(_startNode);
0692:                }
0693:            } // end of RootIterator
0694:
0695:            /**
0696:             * Iterator that returns the namespace nodes as defined by the XPath data model 
0697:             * for a given node, filtered by extended type ID.
0698:             */
0699:            public class TypedRootIterator extends RootIterator {
0700:
0701:                /** The extended type ID that was requested. */
0702:                private final int _nodeType;
0703:
0704:                /**
0705:                 * Constructor TypedRootIterator
0706:                 *
0707:                 * @param nodeType The extended type ID being requested.
0708:                 */
0709:                public TypedRootIterator(int nodeType) {
0710:                    super ();
0711:                    _nodeType = nodeType;
0712:                }
0713:
0714:                /**
0715:                 * Get the next node in the iteration.
0716:                 *
0717:                 * @return The next node handle in the iteration, or END.
0718:                 */
0719:                public int next() {
0720:                    if (_startNode == _currentNode)
0721:                        return NULL;
0722:
0723:                    int nodeType = _nodeType;
0724:                    int node = _startNode;
0725:                    int expType = getExpandedTypeID(node);
0726:
0727:                    _currentNode = node;
0728:
0729:                    if (nodeType >= DTM.NTYPES) {
0730:                        if (nodeType == expType) {
0731:                            return returnNode(node);
0732:                        }
0733:                    } else {
0734:                        if (expType < DTM.NTYPES) {
0735:                            if (expType == nodeType) {
0736:                                return returnNode(node);
0737:                            }
0738:                        } else {
0739:                            if (m_expandedNameTable.getType(expType) == nodeType) {
0740:                                return returnNode(node);
0741:                            }
0742:                        }
0743:                    }
0744:
0745:                    return END;
0746:                }
0747:            } // end of TypedRootIterator
0748:
0749:            /**
0750:             * Iterator that returns attributes within a given namespace for a node.
0751:             */
0752:            public final class NamespaceAttributeIterator extends
0753:                    InternalAxisIteratorBase {
0754:
0755:                /** The extended type ID being requested. */
0756:                private final int _nsType;
0757:
0758:                /**
0759:                 * Constructor NamespaceAttributeIterator
0760:                 *
0761:                 *
0762:                 * @param nsType The extended type ID being requested.
0763:                 */
0764:                public NamespaceAttributeIterator(int nsType) {
0765:
0766:                    super ();
0767:
0768:                    _nsType = nsType;
0769:                }
0770:
0771:                /**
0772:                 * Set start to END should 'close' the iterator,
0773:                 * i.e. subsequent call to next() should return END.
0774:                 *
0775:                 * @param node Sets the root of the iteration.
0776:                 *
0777:                 * @return A DTMAxisIterator set to the start of the iteration.
0778:                 */
0779:                public DTMAxisIterator setStartNode(int node) {
0780:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0781:                    if (node == DTMDefaultBase.ROOTNODE)
0782:                        node = getDocument();
0783:                    if (_isRestartable) {
0784:                        _startNode = node;
0785:                        _currentNode = getFirstNamespaceNode(node, false);
0786:
0787:                        return resetPosition();
0788:                    }
0789:
0790:                    return this ;
0791:                }
0792:
0793:                /**
0794:                 * Get the next node in the iteration.
0795:                 *
0796:                 * @return The next node handle in the iteration, or END.
0797:                 */
0798:                public int next() {
0799:
0800:                    int node = _currentNode;
0801:
0802:                    if (DTM.NULL != node)
0803:                        _currentNode = getNextNamespaceNode(_startNode, node,
0804:                                false);
0805:
0806:                    return returnNode(node);
0807:                }
0808:            } // end of NamespaceAttributeIterator
0809:
0810:            /**
0811:             * Iterator that returns all siblings of a given node.
0812:             */
0813:            public class FollowingSiblingIterator extends
0814:                    InternalAxisIteratorBase {
0815:
0816:                /**
0817:                 * Set start to END should 'close' the iterator,
0818:                 * i.e. subsequent call to next() should return END.
0819:                 *
0820:                 * @param node Sets the root of the iteration.
0821:                 *
0822:                 * @return A DTMAxisIterator set to the start of the iteration.
0823:                 */
0824:                public DTMAxisIterator setStartNode(int node) {
0825:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0826:                    if (node == DTMDefaultBase.ROOTNODE)
0827:                        node = getDocument();
0828:                    if (_isRestartable) {
0829:                        _startNode = node;
0830:                        _currentNode = makeNodeIdentity(node);
0831:
0832:                        return resetPosition();
0833:                    }
0834:
0835:                    return this ;
0836:                }
0837:
0838:                /**
0839:                 * Get the next node in the iteration.
0840:                 *
0841:                 * @return The next node handle in the iteration, or END.
0842:                 */
0843:                public int next() {
0844:                    _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
0845:                            : _nextsib(_currentNode);
0846:                    return returnNode(makeNodeHandle(_currentNode));
0847:                }
0848:            } // end of FollowingSiblingIterator
0849:
0850:            /**
0851:             * Iterator that returns all following siblings of a given node.
0852:             */
0853:            public final class TypedFollowingSiblingIterator extends
0854:                    FollowingSiblingIterator {
0855:
0856:                /** The extended type ID that was requested. */
0857:                private final int _nodeType;
0858:
0859:                /**
0860:                 * Constructor TypedFollowingSiblingIterator
0861:                 *
0862:                 *
0863:                 * @param type The extended type ID being requested.
0864:                 */
0865:                public TypedFollowingSiblingIterator(int type) {
0866:                    _nodeType = type;
0867:                }
0868:
0869:                /**
0870:                 * Get the next node in the iteration.
0871:                 *
0872:                 * @return The next node handle in the iteration, or END.
0873:                 */
0874:                public int next() {
0875:                    if (_currentNode == DTM.NULL) {
0876:                        return DTM.NULL;
0877:                    }
0878:
0879:                    int node = _currentNode;
0880:                    int eType;
0881:                    int nodeType = _nodeType;
0882:
0883:                    if (nodeType >= DTM.NTYPES) {
0884:                        do {
0885:                            node = _nextsib(node);
0886:                        } while (node != DTM.NULL && _exptype(node) != nodeType);
0887:                    } else {
0888:                        while ((node = _nextsib(node)) != DTM.NULL) {
0889:                            eType = _exptype(node);
0890:                            if (eType < DTM.NTYPES) {
0891:                                if (eType == nodeType) {
0892:                                    break;
0893:                                }
0894:                            } else if (m_expandedNameTable.getType(eType) == nodeType) {
0895:                                break;
0896:                            }
0897:                        }
0898:                    }
0899:
0900:                    _currentNode = node;
0901:
0902:                    return (_currentNode == DTM.NULL) ? DTM.NULL
0903:                            : returnNode(makeNodeHandle(_currentNode));
0904:                }
0905:            } // end of TypedFollowingSiblingIterator
0906:
0907:            /**
0908:             * Iterator that returns attribute nodes (of what nodes?)
0909:             */
0910:            public final class AttributeIterator extends
0911:                    InternalAxisIteratorBase {
0912:
0913:                // assumes caller will pass element nodes
0914:
0915:                /**
0916:                 * Set start to END should 'close' the iterator,
0917:                 * i.e. subsequent call to next() should return END.
0918:                 *
0919:                 * @param node Sets the root of the iteration.
0920:                 *
0921:                 * @return A DTMAxisIterator set to the start of the iteration.
0922:                 */
0923:                public DTMAxisIterator setStartNode(int node) {
0924:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
0925:                    if (node == DTMDefaultBase.ROOTNODE)
0926:                        node = getDocument();
0927:                    if (_isRestartable) {
0928:                        _startNode = node;
0929:                        _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
0930:
0931:                        return resetPosition();
0932:                    }
0933:
0934:                    return this ;
0935:                }
0936:
0937:                /**
0938:                 * Get the next node in the iteration.
0939:                 *
0940:                 * @return The next node handle in the iteration, or END.
0941:                 */
0942:                public int next() {
0943:
0944:                    final int node = _currentNode;
0945:
0946:                    if (node != NULL) {
0947:                        _currentNode = getNextAttributeIdentity(node);
0948:                        return returnNode(makeNodeHandle(node));
0949:                    }
0950:
0951:                    return NULL;
0952:                }
0953:            } // end of AttributeIterator
0954:
0955:            /**
0956:             * Iterator that returns attribute nodes of a given type
0957:             */
0958:            public final class TypedAttributeIterator extends
0959:                    InternalAxisIteratorBase {
0960:
0961:                /** The extended type ID that was requested. */
0962:                private final int _nodeType;
0963:
0964:                /**
0965:                 * Constructor TypedAttributeIterator
0966:                 *
0967:                 *
0968:                 * @param nodeType The extended type ID that is requested.
0969:                 */
0970:                public TypedAttributeIterator(int nodeType) {
0971:                    _nodeType = nodeType;
0972:                }
0973:
0974:                // assumes caller will pass element nodes
0975:
0976:                /**
0977:                 * Set start to END should 'close' the iterator,
0978:                 * i.e. subsequent call to next() should return END.
0979:                 *
0980:                 * @param node Sets the root of the iteration.
0981:                 *
0982:                 * @return A DTMAxisIterator set to the start of the iteration.
0983:                 */
0984:                public DTMAxisIterator setStartNode(int node) {
0985:                    if (_isRestartable) {
0986:                        _startNode = node;
0987:
0988:                        _currentNode = getTypedAttribute(node, _nodeType);
0989:
0990:                        return resetPosition();
0991:                    }
0992:
0993:                    return this ;
0994:                }
0995:
0996:                /**
0997:                 * Get the next node in the iteration.
0998:                 *
0999:                 * @return The next node handle in the iteration, or END.
1000:                 */
1001:                public int next() {
1002:
1003:                    final int node = _currentNode;
1004:
1005:                    // singleton iterator, since there can only be one attribute of 
1006:                    // a given type.
1007:                    _currentNode = NULL;
1008:
1009:                    return returnNode(node);
1010:                }
1011:            } // end of TypedAttributeIterator
1012:
1013:            /**
1014:             * Iterator that returns preceding siblings of a given node
1015:             */
1016:            public class PrecedingSiblingIterator extends
1017:                    InternalAxisIteratorBase {
1018:
1019:                /**
1020:                 * The node identity of _startNode for this iterator
1021:                 */
1022:                protected int _startNodeID;
1023:
1024:                /**
1025:                 * True if this iterator has a reversed axis.
1026:                 *
1027:                 * @return true.
1028:                 */
1029:                public boolean isReverse() {
1030:                    return true;
1031:                }
1032:
1033:                /**
1034:                 * Set start to END should 'close' the iterator,
1035:                 * i.e. subsequent call to next() should return END.
1036:                 *
1037:                 * @param node Sets the root of the iteration.
1038:                 *
1039:                 * @return A DTMAxisIterator set to the start of the iteration.
1040:                 */
1041:                public DTMAxisIterator setStartNode(int node) {
1042:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1043:                    if (node == DTMDefaultBase.ROOTNODE)
1044:                        node = getDocument();
1045:                    if (_isRestartable) {
1046:                        _startNode = node;
1047:                        node = _startNodeID = makeNodeIdentity(node);
1048:
1049:                        if (node == NULL) {
1050:                            _currentNode = node;
1051:                            return resetPosition();
1052:                        }
1053:
1054:                        int type = m_expandedNameTable.getType(_exptype(node));
1055:                        if (ExpandedNameTable.ATTRIBUTE == type
1056:                                || ExpandedNameTable.NAMESPACE == type) {
1057:                            _currentNode = node;
1058:                        } else {
1059:                            // Be careful to handle the Document node properly
1060:                            _currentNode = _parent(node);
1061:                            if (NULL != _currentNode)
1062:                                _currentNode = _firstch(_currentNode);
1063:                            else
1064:                                _currentNode = node;
1065:                        }
1066:
1067:                        return resetPosition();
1068:                    }
1069:
1070:                    return this ;
1071:                }
1072:
1073:                /**
1074:                 * Get the next node in the iteration.
1075:                 *
1076:                 * @return The next node handle in the iteration, or END.
1077:                 */
1078:                public int next() {
1079:
1080:                    if (_currentNode == _startNodeID
1081:                            || _currentNode == DTM.NULL) {
1082:                        return NULL;
1083:                    } else {
1084:                        final int node = _currentNode;
1085:                        _currentNode = _nextsib(node);
1086:
1087:                        return returnNode(makeNodeHandle(node));
1088:                    }
1089:                }
1090:            } // end of PrecedingSiblingIterator
1091:
1092:            /**
1093:             * Iterator that returns preceding siblings of a given type for
1094:             * a given node
1095:             */
1096:            public final class TypedPrecedingSiblingIterator extends
1097:                    PrecedingSiblingIterator {
1098:
1099:                /** The extended type ID that was requested. */
1100:                private final int _nodeType;
1101:
1102:                /**
1103:                 * Constructor TypedPrecedingSiblingIterator
1104:                 *
1105:                 *
1106:                 * @param type The extended type ID being requested.
1107:                 */
1108:                public TypedPrecedingSiblingIterator(int type) {
1109:                    _nodeType = type;
1110:                }
1111:
1112:                /**
1113:                 * Get the next node in the iteration.
1114:                 *
1115:                 * @return The next node handle in the iteration, or END.
1116:                 */
1117:                public int next() {
1118:                    int node = _currentNode;
1119:                    int expType;
1120:
1121:                    int nodeType = _nodeType;
1122:                    int startID = _startNodeID;
1123:
1124:                    if (nodeType >= DTM.NTYPES) {
1125:                        while (node != NULL && node != startID
1126:                                && _exptype(node) != nodeType) {
1127:                            node = _nextsib(node);
1128:                        }
1129:                    } else {
1130:                        while (node != NULL && node != startID) {
1131:                            expType = _exptype(node);
1132:                            if (expType < DTM.NTYPES) {
1133:                                if (expType == nodeType) {
1134:                                    break;
1135:                                }
1136:                            } else {
1137:                                if (m_expandedNameTable.getType(expType) == nodeType) {
1138:                                    break;
1139:                                }
1140:                            }
1141:                            node = _nextsib(node);
1142:                        }
1143:                    }
1144:
1145:                    if (node == DTM.NULL || node == _startNodeID) {
1146:                        _currentNode = NULL;
1147:                        return NULL;
1148:                    } else {
1149:                        _currentNode = _nextsib(node);
1150:                        return returnNode(makeNodeHandle(node));
1151:                    }
1152:                }
1153:            } // end of TypedPrecedingSiblingIterator
1154:
1155:            /**
1156:             * Iterator that returns preceding nodes of a given node.
1157:             * This includes the node set {root+1, start-1}, but excludes
1158:             * all ancestors, attributes, and namespace nodes.
1159:             */
1160:            public class PrecedingIterator extends InternalAxisIteratorBase {
1161:
1162:                /** The max ancestors, but it can grow... */
1163:                private final int _maxAncestors = 8;
1164:
1165:                /**
1166:                 * The stack of start node + ancestors up to the root of the tree,
1167:                 *  which we must avoid.
1168:                 */
1169:                protected int[] _stack = new int[_maxAncestors];
1170:
1171:                /** (not sure yet... -sb) */
1172:                protected int _sp, _oldsp;
1173:
1174:                protected int _markedsp, _markedNode, _markedDescendant;
1175:
1176:                /* _currentNode precedes candidates.  This is the identity, not the handle! */
1177:
1178:                /**
1179:                 * True if this iterator has a reversed axis.
1180:                 *
1181:                 * @return true since this iterator is a reversed axis.
1182:                 */
1183:                public boolean isReverse() {
1184:                    return true;
1185:                }
1186:
1187:                /**
1188:                 * Returns a deep copy of this iterator.   The cloned iterator is not reset.
1189:                 *
1190:                 * @return a deep copy of this iterator.
1191:                 */
1192:                public DTMAxisIterator cloneIterator() {
1193:                    _isRestartable = false;
1194:
1195:                    try {
1196:                        final PrecedingIterator clone = (PrecedingIterator) super 
1197:                                .clone();
1198:                        final int[] stackCopy = new int[_stack.length];
1199:                        System
1200:                                .arraycopy(_stack, 0, stackCopy, 0,
1201:                                        _stack.length);
1202:
1203:                        clone._stack = stackCopy;
1204:
1205:                        // return clone.reset();
1206:                        return clone;
1207:                    } catch (CloneNotSupportedException e) {
1208:                        throw new DTMException(
1209:                                XMLMessages
1210:                                        .createXMLMessage(
1211:                                                XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED,
1212:                                                null)); //"Iterator clone not supported.");
1213:                    }
1214:                }
1215:
1216:                /**
1217:                 * Set start to END should 'close' the iterator,
1218:                 * i.e. subsequent call to next() should return END.
1219:                 *
1220:                 * @param node Sets the root of the iteration.
1221:                 *
1222:                 * @return A DTMAxisIterator set to the start of the iteration.
1223:                 */
1224:                public DTMAxisIterator setStartNode(int node) {
1225:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1226:                    if (node == DTMDefaultBase.ROOTNODE)
1227:                        node = getDocument();
1228:                    if (_isRestartable) {
1229:                        node = makeNodeIdentity(node);
1230:
1231:                        // iterator is not a clone
1232:                        int parent, index;
1233:
1234:                        if (_type(node) == DTM.ATTRIBUTE_NODE)
1235:                            node = _parent(node);
1236:
1237:                        _startNode = node;
1238:                        _stack[index = 0] = node;
1239:
1240:                        parent = node;
1241:                        while ((parent = _parent(parent)) != NULL) {
1242:                            if (++index == _stack.length) {
1243:                                final int[] stack = new int[index + 4];
1244:                                System.arraycopy(_stack, 0, stack, 0, index);
1245:                                _stack = stack;
1246:                            }
1247:                            _stack[index] = parent;
1248:                        }
1249:                        if (index > 0)
1250:                            --index; // Pop actual root node (if not start) back off the stack
1251:
1252:                        _currentNode = _stack[index]; // Last parent before root node
1253:
1254:                        _oldsp = _sp = index;
1255:
1256:                        return resetPosition();
1257:                    }
1258:
1259:                    return this ;
1260:                }
1261:
1262:                /**
1263:                 * Get the next node in the iteration.
1264:                 *
1265:                 * @return The next node handle in the iteration, or END.
1266:                 */
1267:                public int next() {
1268:                    // Bugzilla 8324: We were forgetting to skip Attrs and NS nodes.
1269:                    // Also recoded the loop controls for clarity and to flatten out
1270:                    // the tail-recursion.
1271:                    for (++_currentNode; _sp >= 0; ++_currentNode) {
1272:                        if (_currentNode < _stack[_sp]) {
1273:                            if (_type(_currentNode) != ATTRIBUTE_NODE
1274:                                    && _type(_currentNode) != NAMESPACE_NODE)
1275:                                return returnNode(makeNodeHandle(_currentNode));
1276:                        } else
1277:                            --_sp;
1278:                    }
1279:                    return NULL;
1280:                }
1281:
1282:                // redefine DTMAxisIteratorBase's reset
1283:
1284:                /**
1285:                 * Resets the iterator to the last start node.
1286:                 *
1287:                 * @return A DTMAxisIterator, which may or may not be the same as this
1288:                 *         iterator.
1289:                 */
1290:                public DTMAxisIterator reset() {
1291:
1292:                    _sp = _oldsp;
1293:
1294:                    return resetPosition();
1295:                }
1296:
1297:                public void setMark() {
1298:                    _markedsp = _sp;
1299:                    _markedNode = _currentNode;
1300:                    _markedDescendant = _stack[0];
1301:                }
1302:
1303:                public void gotoMark() {
1304:                    _sp = _markedsp;
1305:                    _currentNode = _markedNode;
1306:                }
1307:            } // end of PrecedingIterator
1308:
1309:            /**
1310:             * Iterator that returns preceding nodes of agiven type for a
1311:             * given node. This includes the node set {root+1, start-1}, but
1312:             * excludes all ancestors.
1313:             */
1314:            public final class TypedPrecedingIterator extends PrecedingIterator {
1315:
1316:                /** The extended type ID that was requested. */
1317:                private final int _nodeType;
1318:
1319:                /**
1320:                 * Constructor TypedPrecedingIterator
1321:                 *
1322:                 *
1323:                 * @param type The extended type ID being requested.
1324:                 */
1325:                public TypedPrecedingIterator(int type) {
1326:                    _nodeType = type;
1327:                }
1328:
1329:                /**
1330:                 * Get the next node in the iteration.
1331:                 *
1332:                 * @return The next node handle in the iteration, or END.
1333:                 */
1334:                public int next() {
1335:                    int node = _currentNode;
1336:                    int nodeType = _nodeType;
1337:
1338:                    if (nodeType >= DTM.NTYPES) {
1339:                        while (true) {
1340:                            node = node + 1;
1341:
1342:                            if (_sp < 0) {
1343:                                node = NULL;
1344:                                break;
1345:                            } else if (node >= _stack[_sp]) {
1346:                                if (--_sp < 0) {
1347:                                    node = NULL;
1348:                                    break;
1349:                                }
1350:                            } else if (_exptype(node) == nodeType) {
1351:                                break;
1352:                            }
1353:                        }
1354:                    } else {
1355:                        int expType;
1356:
1357:                        while (true) {
1358:                            node = node + 1;
1359:
1360:                            if (_sp < 0) {
1361:                                node = NULL;
1362:                                break;
1363:                            } else if (node >= _stack[_sp]) {
1364:                                if (--_sp < 0) {
1365:                                    node = NULL;
1366:                                    break;
1367:                                }
1368:                            } else {
1369:                                expType = _exptype(node);
1370:                                if (expType < DTM.NTYPES) {
1371:                                    if (expType == nodeType) {
1372:                                        break;
1373:                                    }
1374:                                } else {
1375:                                    if (m_expandedNameTable.getType(expType) == nodeType) {
1376:                                        break;
1377:                                    }
1378:                                }
1379:                            }
1380:                        }
1381:                    }
1382:
1383:                    _currentNode = node;
1384:
1385:                    return (node == NULL) ? NULL
1386:                            : returnNode(makeNodeHandle(node));
1387:                }
1388:            } // end of TypedPrecedingIterator
1389:
1390:            /**
1391:             * Iterator that returns following nodes of for a given node.
1392:             */
1393:            public class FollowingIterator extends InternalAxisIteratorBase {
1394:                DTMAxisTraverser m_traverser; // easier for now
1395:
1396:                public FollowingIterator() {
1397:                    m_traverser = getAxisTraverser(Axis.FOLLOWING);
1398:                }
1399:
1400:                /**
1401:                 * Set start to END should 'close' the iterator,
1402:                 * i.e. subsequent call to next() should return END.
1403:                 *
1404:                 * @param node Sets the root of the iteration.
1405:                 *
1406:                 * @return A DTMAxisIterator set to the start of the iteration.
1407:                 */
1408:                public DTMAxisIterator setStartNode(int node) {
1409:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1410:                    if (node == DTMDefaultBase.ROOTNODE)
1411:                        node = getDocument();
1412:                    if (_isRestartable) {
1413:                        _startNode = node;
1414:
1415:                        // ?? -sb
1416:                        // find rightmost descendant (or self)
1417:                        // int current;
1418:                        // while ((node = getLastChild(current = node)) != NULL){}
1419:                        // _currentNode = current;
1420:                        _currentNode = m_traverser.first(node);
1421:
1422:                        // _currentNode precedes possible following(node) nodes
1423:                        return resetPosition();
1424:                    }
1425:
1426:                    return this ;
1427:                }
1428:
1429:                /**
1430:                 * Get the next node in the iteration.
1431:                 *
1432:                 * @return The next node handle in the iteration, or END.
1433:                 */
1434:                public int next() {
1435:
1436:                    int node = _currentNode;
1437:
1438:                    _currentNode = m_traverser.next(_startNode, _currentNode);
1439:
1440:                    return returnNode(node);
1441:                }
1442:            } // end of FollowingIterator
1443:
1444:            /**
1445:             * Iterator that returns following nodes of a given type for a given node.
1446:             */
1447:            public final class TypedFollowingIterator extends FollowingIterator {
1448:
1449:                /** The extended type ID that was requested. */
1450:                private final int _nodeType;
1451:
1452:                /**
1453:                 * Constructor TypedFollowingIterator
1454:                 *
1455:                 *
1456:                 * @param type The extended type ID being requested.
1457:                 */
1458:                public TypedFollowingIterator(int type) {
1459:                    _nodeType = type;
1460:                }
1461:
1462:                /**
1463:                 * Get the next node in the iteration.
1464:                 *
1465:                 * @return The next node handle in the iteration, or END.
1466:                 */
1467:                public int next() {
1468:
1469:                    int node;
1470:
1471:                    do {
1472:                        node = _currentNode;
1473:
1474:                        _currentNode = m_traverser.next(_startNode,
1475:                                _currentNode);
1476:
1477:                    } while (node != DTM.NULL
1478:                            && (getExpandedTypeID(node) != _nodeType && getNodeType(node) != _nodeType));
1479:
1480:                    return (node == DTM.NULL ? DTM.NULL : returnNode(node));
1481:                }
1482:            } // end of TypedFollowingIterator
1483:
1484:            /**
1485:             * Iterator that returns the ancestors of a given node in document
1486:             * order.  (NOTE!  This was changed from the XSLTC code!)
1487:             */
1488:            public class AncestorIterator extends InternalAxisIteratorBase {
1489:                org.apache.xml.utils.NodeVector m_ancestors = new org.apache.xml.utils.NodeVector();
1490:
1491:                int m_ancestorsPos;
1492:
1493:                int m_markedPos;
1494:
1495:                /** The real start node for this axes, since _startNode will be adjusted. */
1496:                int m_realStartNode;
1497:
1498:                /**
1499:                 * Get start to END should 'close' the iterator,
1500:                 * i.e. subsequent call to next() should return END.
1501:                 *
1502:                 * @return The root node of the iteration.
1503:                 */
1504:                public int getStartNode() {
1505:                    return m_realStartNode;
1506:                }
1507:
1508:                /**
1509:                 * True if this iterator has a reversed axis.
1510:                 *
1511:                 * @return true since this iterator is a reversed axis.
1512:                 */
1513:                public final boolean isReverse() {
1514:                    return true;
1515:                }
1516:
1517:                /**
1518:                 * Returns a deep copy of this iterator.  The cloned iterator is not reset.
1519:                 *
1520:                 * @return a deep copy of this iterator.
1521:                 */
1522:                public DTMAxisIterator cloneIterator() {
1523:                    _isRestartable = false; // must set to false for any clone
1524:
1525:                    try {
1526:                        final AncestorIterator clone = (AncestorIterator) super 
1527:                                .clone();
1528:
1529:                        clone._startNode = _startNode;
1530:
1531:                        // return clone.reset();
1532:                        return clone;
1533:                    } catch (CloneNotSupportedException e) {
1534:                        throw new DTMException(
1535:                                XMLMessages
1536:                                        .createXMLMessage(
1537:                                                XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED,
1538:                                                null)); //"Iterator clone not supported.");
1539:                    }
1540:                }
1541:
1542:                /**
1543:                 * Set start to END should 'close' the iterator,
1544:                 * i.e. subsequent call to next() should return END.
1545:                 *
1546:                 * @param node Sets the root of the iteration.
1547:                 *
1548:                 * @return A DTMAxisIterator set to the start of the iteration.
1549:                 */
1550:                public DTMAxisIterator setStartNode(int node) {
1551:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1552:                    if (node == DTMDefaultBase.ROOTNODE)
1553:                        node = getDocument();
1554:                    m_realStartNode = node;
1555:
1556:                    if (_isRestartable) {
1557:                        int nodeID = makeNodeIdentity(node);
1558:
1559:                        if (!_includeSelf && node != DTM.NULL) {
1560:                            nodeID = _parent(nodeID);
1561:                            node = makeNodeHandle(nodeID);
1562:                        }
1563:
1564:                        _startNode = node;
1565:
1566:                        while (nodeID != END) {
1567:                            m_ancestors.addElement(node);
1568:                            nodeID = _parent(nodeID);
1569:                            node = makeNodeHandle(nodeID);
1570:                        }
1571:                        m_ancestorsPos = m_ancestors.size() - 1;
1572:
1573:                        _currentNode = (m_ancestorsPos >= 0) ? m_ancestors
1574:                                .elementAt(m_ancestorsPos) : DTM.NULL;
1575:
1576:                        return resetPosition();
1577:                    }
1578:
1579:                    return this ;
1580:                }
1581:
1582:                /**
1583:                 * Resets the iterator to the last start node.
1584:                 *
1585:                 * @return A DTMAxisIterator, which may or may not be the same as this
1586:                 *         iterator.
1587:                 */
1588:                public DTMAxisIterator reset() {
1589:
1590:                    m_ancestorsPos = m_ancestors.size() - 1;
1591:
1592:                    _currentNode = (m_ancestorsPos >= 0) ? m_ancestors
1593:                            .elementAt(m_ancestorsPos) : DTM.NULL;
1594:
1595:                    return resetPosition();
1596:                }
1597:
1598:                /**
1599:                 * Get the next node in the iteration.
1600:                 *
1601:                 * @return The next node handle in the iteration, or END.
1602:                 */
1603:                public int next() {
1604:
1605:                    int next = _currentNode;
1606:
1607:                    int pos = --m_ancestorsPos;
1608:
1609:                    _currentNode = (pos >= 0) ? m_ancestors
1610:                            .elementAt(m_ancestorsPos) : DTM.NULL;
1611:
1612:                    return returnNode(next);
1613:                }
1614:
1615:                public void setMark() {
1616:                    m_markedPos = m_ancestorsPos;
1617:                }
1618:
1619:                public void gotoMark() {
1620:                    m_ancestorsPos = m_markedPos;
1621:                    _currentNode = m_ancestorsPos >= 0 ? m_ancestors
1622:                            .elementAt(m_ancestorsPos) : DTM.NULL;
1623:                }
1624:            } // end of AncestorIterator
1625:
1626:            /**
1627:             * Typed iterator that returns the ancestors of a given node.
1628:             */
1629:            public final class TypedAncestorIterator extends AncestorIterator {
1630:
1631:                /** The extended type ID that was requested. */
1632:                private final int _nodeType;
1633:
1634:                /**
1635:                 * Constructor TypedAncestorIterator
1636:                 *
1637:                 *
1638:                 * @param type The extended type ID being requested.
1639:                 */
1640:                public TypedAncestorIterator(int type) {
1641:                    _nodeType = type;
1642:                }
1643:
1644:                /**
1645:                 * Set start to END should 'close' the iterator,
1646:                 * i.e. subsequent call to next() should return END.
1647:                 *
1648:                 * @param node Sets the root of the iteration.
1649:                 *
1650:                 * @return A DTMAxisIterator set to the start of the iteration.
1651:                 */
1652:                public DTMAxisIterator setStartNode(int node) {
1653:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1654:                    if (node == DTMDefaultBase.ROOTNODE)
1655:                        node = getDocument();
1656:                    m_realStartNode = node;
1657:
1658:                    if (_isRestartable) {
1659:                        int nodeID = makeNodeIdentity(node);
1660:                        int nodeType = _nodeType;
1661:
1662:                        if (!_includeSelf && node != DTM.NULL) {
1663:                            nodeID = _parent(nodeID);
1664:                        }
1665:
1666:                        _startNode = node;
1667:
1668:                        if (nodeType >= DTM.NTYPES) {
1669:                            while (nodeID != END) {
1670:                                int eType = _exptype(nodeID);
1671:
1672:                                if (eType == nodeType) {
1673:                                    m_ancestors
1674:                                            .addElement(makeNodeHandle(nodeID));
1675:                                }
1676:                                nodeID = _parent(nodeID);
1677:                            }
1678:                        } else {
1679:                            while (nodeID != END) {
1680:                                int eType = _exptype(nodeID);
1681:
1682:                                if ((eType >= DTM.NTYPES && m_expandedNameTable
1683:                                        .getType(eType) == nodeType)
1684:                                        || (eType < DTM.NTYPES && eType == nodeType)) {
1685:                                    m_ancestors
1686:                                            .addElement(makeNodeHandle(nodeID));
1687:                                }
1688:                                nodeID = _parent(nodeID);
1689:                            }
1690:                        }
1691:                        m_ancestorsPos = m_ancestors.size() - 1;
1692:
1693:                        _currentNode = (m_ancestorsPos >= 0) ? m_ancestors
1694:                                .elementAt(m_ancestorsPos) : DTM.NULL;
1695:
1696:                        return resetPosition();
1697:                    }
1698:
1699:                    return this ;
1700:                }
1701:            } // end of TypedAncestorIterator
1702:
1703:            /**
1704:             * Iterator that returns the descendants of a given node.
1705:             */
1706:            public class DescendantIterator extends InternalAxisIteratorBase {
1707:
1708:                /**
1709:                 * Set start to END should 'close' the iterator,
1710:                 * i.e. subsequent call to next() should return END.
1711:                 *
1712:                 * @param node Sets the root of the iteration.
1713:                 *
1714:                 * @return A DTMAxisIterator set to the start of the iteration.
1715:                 */
1716:                public DTMAxisIterator setStartNode(int node) {
1717:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1718:                    if (node == DTMDefaultBase.ROOTNODE)
1719:                        node = getDocument();
1720:                    if (_isRestartable) {
1721:                        node = makeNodeIdentity(node);
1722:                        _startNode = node;
1723:
1724:                        if (_includeSelf)
1725:                            node--;
1726:
1727:                        _currentNode = node;
1728:
1729:                        return resetPosition();
1730:                    }
1731:
1732:                    return this ;
1733:                }
1734:
1735:                /**
1736:                 * Tell if this node identity is a descendant.  Assumes that
1737:                 * the node info for the element has already been obtained.
1738:                 *
1739:                 * This one-sided test works only if the parent has been
1740:                 * previously tested and is known to be a descendent. It fails if
1741:                 * the parent is the _startNode's next sibling, or indeed any node
1742:                 * that follows _startNode in document order.  That may suffice
1743:                 * for this iterator, but it's not really an isDescendent() test.
1744:                 * %REVIEW% rename?
1745:                 *
1746:                 * @param identity The index number of the node in question.
1747:                 * @return true if the index is a descendant of _startNode.
1748:                 */
1749:                protected boolean isDescendant(int identity) {
1750:                    return (_parent(identity) >= _startNode)
1751:                            || (_startNode == identity);
1752:                }
1753:
1754:                /**
1755:                 * Get the next node in the iteration.
1756:                 *
1757:                 * @return The next node handle in the iteration, or END.
1758:                 */
1759:                public int next() {
1760:                    if (_startNode == NULL) {
1761:                        return NULL;
1762:                    }
1763:
1764:                    if (_includeSelf && (_currentNode + 1) == _startNode)
1765:                        return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent);
1766:
1767:                    int node = _currentNode;
1768:                    int type;
1769:
1770:                    do {
1771:                        node++;
1772:                        type = _type(node);
1773:
1774:                        if (NULL == type || !isDescendant(node)) {
1775:                            _currentNode = NULL;
1776:                            return END;
1777:                        }
1778:                    } while (ATTRIBUTE_NODE == type || TEXT_NODE == type
1779:                            || NAMESPACE_NODE == type);
1780:
1781:                    _currentNode = node;
1782:                    return returnNode(makeNodeHandle(node)); // make handle.
1783:                }
1784:
1785:                /**
1786:                 * Reset.
1787:                 *
1788:                 */
1789:                public DTMAxisIterator reset() {
1790:
1791:                    final boolean temp = _isRestartable;
1792:
1793:                    _isRestartable = true;
1794:
1795:                    setStartNode(makeNodeHandle(_startNode));
1796:
1797:                    _isRestartable = temp;
1798:
1799:                    return this ;
1800:                }
1801:
1802:            } // end of DescendantIterator
1803:
1804:            /**
1805:             * Typed iterator that returns the descendants of a given node.
1806:             */
1807:            public final class TypedDescendantIterator extends
1808:                    DescendantIterator {
1809:
1810:                /** The extended type ID that was requested. */
1811:                private final int _nodeType;
1812:
1813:                /**
1814:                 * Constructor TypedDescendantIterator
1815:                 *
1816:                 *
1817:                 * @param nodeType Extended type ID being requested.
1818:                 */
1819:                public TypedDescendantIterator(int nodeType) {
1820:                    _nodeType = nodeType;
1821:                }
1822:
1823:                /**
1824:                 * Get the next node in the iteration.
1825:                 *
1826:                 * @return The next node handle in the iteration, or END.
1827:                 */
1828:                public int next() {
1829:                    int node;
1830:                    int type;
1831:
1832:                    if (_startNode == NULL) {
1833:                        return NULL;
1834:                    }
1835:
1836:                    node = _currentNode;
1837:
1838:                    do {
1839:                        node++;
1840:                        type = _type(node);
1841:
1842:                        if (NULL == type || !isDescendant(node)) {
1843:                            _currentNode = NULL;
1844:                            return END;
1845:                        }
1846:                    } while (type != _nodeType && _exptype(node) != _nodeType);
1847:
1848:                    _currentNode = node;
1849:                    return returnNode(makeNodeHandle(node));
1850:                }
1851:            } // end of TypedDescendantIterator
1852:
1853:            /**
1854:             * Iterator that returns the descendants of a given node.
1855:             * I'm not exactly clear about this one... -sb
1856:             */
1857:            public class NthDescendantIterator extends DescendantIterator {
1858:
1859:                /** The current nth position. */
1860:                int _pos;
1861:
1862:                /**
1863:                 * Constructor NthDescendantIterator
1864:                 *
1865:                 *
1866:                 * @param pos The nth position being requested.
1867:                 */
1868:                public NthDescendantIterator(int pos) {
1869:                    _pos = pos;
1870:                }
1871:
1872:                /**
1873:                 * Get the next node in the iteration.
1874:                 *
1875:                 * @return The next node handle in the iteration, or END.
1876:                 */
1877:                public int next() {
1878:
1879:                    // I'm not exactly clear yet what this is doing... -sb
1880:                    int node;
1881:
1882:                    while ((node = super .next()) != END) {
1883:                        node = makeNodeIdentity(node);
1884:
1885:                        int parent = _parent(node);
1886:                        int child = _firstch(parent);
1887:                        int pos = 0;
1888:
1889:                        do {
1890:                            int type = _type(child);
1891:
1892:                            if (ELEMENT_NODE == type)
1893:                                pos++;
1894:                        } while ((pos < _pos)
1895:                                && (child = _nextsib(child)) != END);
1896:
1897:                        if (node == child)
1898:                            return node;
1899:                    }
1900:
1901:                    return (END);
1902:                }
1903:            } // end of NthDescendantIterator
1904:
1905:            /**
1906:             * Class SingletonIterator.
1907:             */
1908:            public class SingletonIterator extends InternalAxisIteratorBase {
1909:
1910:                /** (not sure yet what this is.  -sb)  (sc & sb remove final to compile in JDK 1.1.8) */
1911:                private boolean _isConstant;
1912:
1913:                /**
1914:                 * Constructor SingletonIterator
1915:                 *
1916:                 */
1917:                public SingletonIterator() {
1918:                    this (Integer.MIN_VALUE, false);
1919:                }
1920:
1921:                /**
1922:                 * Constructor SingletonIterator
1923:                 *
1924:                 *
1925:                 * @param node The node handle to return.
1926:                 */
1927:                public SingletonIterator(int node) {
1928:                    this (node, false);
1929:                }
1930:
1931:                /**
1932:                 * Constructor SingletonIterator
1933:                 *
1934:                 *
1935:                 * @param node the node handle to return.
1936:                 * @param constant (Not sure what this is yet.  -sb)
1937:                 */
1938:                public SingletonIterator(int node, boolean constant) {
1939:                    _currentNode = _startNode = node;
1940:                    _isConstant = constant;
1941:                }
1942:
1943:                /**
1944:                 * Set start to END should 'close' the iterator,
1945:                 * i.e. subsequent call to next() should return END.
1946:                 *
1947:                 * @param node Sets the root of the iteration.
1948:                 *
1949:                 * @return A DTMAxisIterator set to the start of the iteration.
1950:                 */
1951:                public DTMAxisIterator setStartNode(int node) {
1952:                    //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
1953:                    if (node == DTMDefaultBase.ROOTNODE)
1954:                        node = getDocument();
1955:                    if (_isConstant) {
1956:                        _currentNode = _startNode;
1957:
1958:                        return resetPosition();
1959:                    } else if (_isRestartable) {
1960:                        if (_currentNode == Integer.MIN_VALUE) {
1961:                            _currentNode = _startNode = node;
1962:                        }
1963:
1964:                        return resetPosition();
1965:                    }
1966:
1967:                    return this ;
1968:                }
1969:
1970:                /**
1971:                 * Resets the iterator to the last start node.
1972:                 *
1973:                 * @return A DTMAxisIterator, which may or may not be the same as this
1974:                 *         iterator.
1975:                 */
1976:                public DTMAxisIterator reset() {
1977:
1978:                    if (_isConstant) {
1979:                        _currentNode = _startNode;
1980:
1981:                        return resetPosition();
1982:                    } else {
1983:                        final boolean temp = _isRestartable;
1984:
1985:                        _isRestartable = true;
1986:
1987:                        setStartNode(_startNode);
1988:
1989:                        _isRestartable = temp;
1990:                    }
1991:
1992:                    return this ;
1993:                }
1994:
1995:                /**
1996:                 * Get the next node in the iteration.
1997:                 *
1998:                 * @return The next node handle in the iteration, or END.
1999:                 */
2000:                public int next() {
2001:
2002:                    final int result = _currentNode;
2003:
2004:                    _currentNode = END;
2005:
2006:                    return returnNode(result);
2007:                }
2008:            } // end of SingletonIterator
2009:
2010:            /**
2011:             * Iterator that returns a given node only if it is of a given type.
2012:             */
2013:            public final class TypedSingletonIterator extends SingletonIterator {
2014:
2015:                /** The extended type ID that was requested. */
2016:                private final int _nodeType;
2017:
2018:                /**
2019:                 * Constructor TypedSingletonIterator
2020:                 *
2021:                 *
2022:                 * @param nodeType The extended type ID being requested.
2023:                 */
2024:                public TypedSingletonIterator(int nodeType) {
2025:                    _nodeType = nodeType;
2026:                }
2027:
2028:                /**
2029:                 * Get the next node in the iteration.
2030:                 *
2031:                 * @return The next node handle in the iteration, or END.
2032:                 */
2033:                public int next() {
2034:
2035:                    //final int result = super.next();
2036:                    final int result = _currentNode;
2037:                    int nodeType = _nodeType;
2038:
2039:                    _currentNode = END;
2040:
2041:                    if (nodeType >= DTM.NTYPES) {
2042:                        if (getExpandedTypeID(result) == nodeType) {
2043:                            return returnNode(result);
2044:                        }
2045:                    } else {
2046:                        if (getNodeType(result) == nodeType) {
2047:                            return returnNode(result);
2048:                        }
2049:                    }
2050:
2051:                    return NULL;
2052:                }
2053:            } // end of TypedSingletonIterator
2054:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.