Source Code Cross Referenced for XPathContext.java in  » XML » xalan » org » apache » xpath » 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.xpath 
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: XPathContext.java,v 1.55 2005/06/07 15:35:52 mkwan Exp $
0018:         */
0019:        package org.apache.xpath;
0020:
0021:        import java.lang.reflect.Method;
0022:        import java.util.Stack;
0023:        import java.util.Vector;
0024:        import java.util.HashMap;
0025:        import java.util.Iterator;
0026:
0027:        import javax.xml.transform.ErrorListener;
0028:        import javax.xml.transform.SourceLocator;
0029:        import javax.xml.transform.TransformerException;
0030:        import javax.xml.transform.URIResolver;
0031:
0032:        import org.apache.xalan.extensions.ExpressionContext;
0033:        import org.apache.xalan.res.XSLMessages;
0034:        import org.apache.xml.dtm.Axis;
0035:        import org.apache.xml.dtm.DTM;
0036:        import org.apache.xml.dtm.DTMFilter;
0037:        import org.apache.xml.dtm.DTMIterator;
0038:        import org.apache.xml.dtm.DTMManager;
0039:        import org.apache.xml.dtm.DTMWSFilter;
0040:        import org.apache.xml.dtm.ref.sax2dtm.SAX2RTFDTM;
0041:        import org.apache.xml.utils.IntStack;
0042:        import org.apache.xml.utils.NodeVector;
0043:        import org.apache.xml.utils.ObjectStack;
0044:        import org.apache.xml.utils.PrefixResolver;
0045:        import org.apache.xml.utils.SAXSourceLocator;
0046:        import org.apache.xml.utils.XMLString;
0047:        import org.apache.xpath.axes.SubContextList;
0048:        import org.apache.xpath.objects.XObject;
0049:        import org.apache.xpath.objects.DTMXRTreeFrag;
0050:        import org.apache.xpath.objects.XString;
0051:        import org.apache.xpath.res.XPATHErrorResources;
0052:
0053:        import org.xml.sax.XMLReader;
0054:
0055:        /**
0056:         * Default class for the runtime execution context for XPath.
0057:         * 
0058:         * <p>This class extends DTMManager but does not directly implement it.</p>
0059:         * @xsl.usage advanced
0060:         */
0061:        public class XPathContext extends DTMManager // implements ExpressionContext
0062:        {
0063:            IntStack m_last_pushed_rtfdtm = new IntStack();
0064:            /**
0065:             * Stack of cached "reusable" DTMs for Result Tree Fragments.
0066:             * This is a kluge to handle the problem of starting an RTF before
0067:             * the old one is complete.
0068:             * 
0069:             * %REVIEW% I'm using a Vector rather than Stack so we can reuse
0070:             * the DTMs if the problem occurs multiple times. I'm not sure that's
0071:             * really a net win versus discarding the DTM and starting a new one...
0072:             * but the retained RTF DTM will have been tail-pruned so should be small.
0073:             */
0074:            private Vector m_rtfdtm_stack = null;
0075:            /** Index of currently active RTF DTM in m_rtfdtm_stack */
0076:            private int m_which_rtfdtm = -1;
0077:
0078:            /**
0079:             * Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
0080:             * required since we're never going to pop these.
0081:             */
0082:            private SAX2RTFDTM m_global_rtfdtm = null;
0083:
0084:            /**
0085:             * HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
0086:             * The object are just wrappers for DTMs which are used in  XRTreeFrag.
0087:             */
0088:            private HashMap m_DTMXRTreeFrags = null;
0089:
0090:            /**
0091:             * state of the secure processing feature.
0092:             */
0093:            private boolean m_isSecureProcessing = false;
0094:
0095:            /**
0096:             * Though XPathContext context extends 
0097:             * the DTMManager, it really is a proxy for this object, which 
0098:             * is the real DTMManager.
0099:             */
0100:            protected DTMManager m_dtmManager = DTMManager
0101:                    .newInstance(org.apache.xpath.objects.XMLStringFactoryImpl
0102:                            .getFactory());
0103:
0104:            /**
0105:             * Return the DTMManager object.  Though XPathContext context extends 
0106:             * the DTMManager, it really is a proxy for the real DTMManager.  If a 
0107:             * caller needs to make a lot of calls to the DTMManager, it is faster 
0108:             * if it gets the real one from this function.
0109:             */
0110:            public DTMManager getDTMManager() {
0111:                return m_dtmManager;
0112:            }
0113:
0114:            /**
0115:             * Set the state of the secure processing feature
0116:             */
0117:            public void setSecureProcessing(boolean flag) {
0118:                m_isSecureProcessing = flag;
0119:            }
0120:
0121:            /**
0122:             * Return the state of the secure processing feature
0123:             */
0124:            public boolean isSecureProcessing() {
0125:                return m_isSecureProcessing;
0126:            }
0127:
0128:            /**
0129:             * Get an instance of a DTM, loaded with the content from the
0130:             * specified source.  If the unique flag is true, a new instance will
0131:             * always be returned.  Otherwise it is up to the DTMManager to return a
0132:             * new instance or an instance that it already created and may be being used
0133:             * by someone else.
0134:             * (I think more parameters will need to be added for error handling, and entity
0135:             * resolution).
0136:             *
0137:             * @param source the specification of the source object, which may be null, 
0138:             *               in which case it is assumed that node construction will take 
0139:             *               by some other means.
0140:             * @param unique true if the returned DTM must be unique, probably because it
0141:             * is going to be mutated.
0142:             * @param wsfilter Enables filtering of whitespace nodes, and may be null.
0143:             * @param incremental true if the construction should try and be incremental.
0144:             * @param doIndexing true if the caller considers it worth it to use 
0145:             *                   indexing schemes.
0146:             *
0147:             * @return a non-null DTM reference.
0148:             */
0149:            public DTM getDTM(javax.xml.transform.Source source,
0150:                    boolean unique, DTMWSFilter wsfilter, boolean incremental,
0151:                    boolean doIndexing) {
0152:                return m_dtmManager.getDTM(source, unique, wsfilter,
0153:                        incremental, doIndexing);
0154:            }
0155:
0156:            /**
0157:             * Get an instance of a DTM that "owns" a node handle. 
0158:             *
0159:             * @param nodeHandle the nodeHandle.
0160:             *
0161:             * @return a non-null DTM reference.
0162:             */
0163:            public DTM getDTM(int nodeHandle) {
0164:                return m_dtmManager.getDTM(nodeHandle);
0165:            }
0166:
0167:            /**
0168:             * Given a W3C DOM node, try and return a DTM handle.
0169:             * Note: calling this may be non-optimal.
0170:             * 
0171:             * @param node Non-null reference to a DOM node.
0172:             * 
0173:             * @return a valid DTM handle.
0174:             */
0175:            public int getDTMHandleFromNode(org.w3c.dom.Node node) {
0176:                return m_dtmManager.getDTMHandleFromNode(node);
0177:            }
0178:
0179:            //
0180:            //  
0181:            /**
0182:             * %TBD% Doc
0183:             */
0184:            public int getDTMIdentity(DTM dtm) {
0185:                return m_dtmManager.getDTMIdentity(dtm);
0186:            }
0187:
0188:            //  
0189:            /**
0190:             * Creates an empty <code>DocumentFragment</code> object. 
0191:             * @return A new <code>DocumentFragment handle</code>.
0192:             */
0193:            public DTM createDocumentFragment() {
0194:                return m_dtmManager.createDocumentFragment();
0195:            }
0196:
0197:            //  
0198:            /**
0199:             * Release a DTM either to a lru pool, or completely remove reference.
0200:             * DTMs without system IDs are always hard deleted.
0201:             * State: experimental.
0202:             * 
0203:             * @param dtm The DTM to be released.
0204:             * @param shouldHardDelete True if the DTM should be removed no matter what.
0205:             * @return true if the DTM was removed, false if it was put back in a lru pool.
0206:             */
0207:            public boolean release(DTM dtm, boolean shouldHardDelete) {
0208:                // %REVIEW% If it's a DTM which may contain multiple Result Tree
0209:                // Fragments, we can't discard it unless we know not only that it
0210:                // is empty, but that the XPathContext itself is going away. So do
0211:                // _not_ accept the request. (May want to do it as part of
0212:                // reset(), though.)
0213:                if (m_rtfdtm_stack != null && m_rtfdtm_stack.contains(dtm)) {
0214:                    return false;
0215:                }
0216:
0217:                return m_dtmManager.release(dtm, shouldHardDelete);
0218:            }
0219:
0220:            /**
0221:             * Create a new <code>DTMIterator</code> based on an XPath
0222:             * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
0223:             * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
0224:             *
0225:             * @param xpathCompiler ??? Somehow we need to pass in a subpart of the
0226:             * expression.  I hate to do this with strings, since the larger expression
0227:             * has already been parsed.
0228:             *
0229:             * @param pos The position in the expression.
0230:             * @return The newly created <code>DTMIterator</code>.
0231:             */
0232:            public DTMIterator createDTMIterator(Object xpathCompiler, int pos) {
0233:                return m_dtmManager.createDTMIterator(xpathCompiler, pos);
0234:            }
0235:
0236:            //
0237:            /**
0238:             * Create a new <code>DTMIterator</code> based on an XPath
0239:             * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
0240:             * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
0241:             *
0242:             * @param xpathString Must be a valid string expressing a
0243:             * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
0244:             * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
0245:             *
0246:             * @param presolver An object that can resolve prefixes to namespace URLs.
0247:             *
0248:             * @return The newly created <code>DTMIterator</code>.
0249:             */
0250:            public DTMIterator createDTMIterator(String xpathString,
0251:                    PrefixResolver presolver) {
0252:                return m_dtmManager.createDTMIterator(xpathString, presolver);
0253:            }
0254:
0255:            //
0256:            /**
0257:             * Create a new <code>DTMIterator</code> based only on a whatToShow and
0258:             * a DTMFilter.  The traversal semantics are defined as the descendant
0259:             * access.
0260:             *
0261:             * @param whatToShow This flag specifies which node types may appear in
0262:             *   the logical view of the tree presented by the iterator. See the
0263:             *   description of <code>NodeFilter</code> for the set of possible
0264:             *   <code>SHOW_</code> values.These flags can be combined using
0265:             *   <code>OR</code>.
0266:             * @param filter The <code>NodeFilter</code> to be used with this
0267:             *   <code>TreeWalker</code>, or <code>null</code> to indicate no filter.
0268:             * @param entityReferenceExpansion The value of this flag determines
0269:             *   whether entity reference nodes are expanded.
0270:             *
0271:             * @return The newly created <code>NodeIterator</code>.
0272:             */
0273:            public DTMIterator createDTMIterator(int whatToShow,
0274:                    DTMFilter filter, boolean entityReferenceExpansion) {
0275:                return m_dtmManager.createDTMIterator(whatToShow, filter,
0276:                        entityReferenceExpansion);
0277:            }
0278:
0279:            /**
0280:             * Create a new <code>DTMIterator</code> that holds exactly one node.
0281:             *
0282:             * @param node The node handle that the DTMIterator will iterate to.
0283:             *
0284:             * @return The newly created <code>DTMIterator</code>.
0285:             */
0286:            public DTMIterator createDTMIterator(int node) {
0287:                // DescendantIterator iter = new DescendantIterator();
0288:                DTMIterator iter = new org.apache.xpath.axes.OneStepIteratorForward(
0289:                        Axis.SELF);
0290:                iter.setRoot(node, this );
0291:                return iter;
0292:                // return m_dtmManager.createDTMIterator(node);
0293:            }
0294:
0295:            /**
0296:             * Create an XPathContext instance.
0297:             */
0298:            public XPathContext() {
0299:                m_prefixResolvers.push(null);
0300:                m_currentNodes.push(DTM.NULL);
0301:                m_currentExpressionNodes.push(DTM.NULL);
0302:                m_saxLocations.push(null);
0303:            }
0304:
0305:            /**
0306:             * Create an XPathContext instance.
0307:             * @param owner Value that can be retrieved via the getOwnerObject() method.
0308:             * @see #getOwnerObject
0309:             */
0310:            public XPathContext(Object owner) {
0311:                m_owner = owner;
0312:                try {
0313:                    m_ownerGetErrorListener = m_owner.getClass().getMethod(
0314:                            "getErrorListener", new Class[] {});
0315:                } catch (NoSuchMethodException nsme) {
0316:                }
0317:                m_prefixResolvers.push(null);
0318:                m_currentNodes.push(DTM.NULL);
0319:                m_currentExpressionNodes.push(DTM.NULL);
0320:                m_saxLocations.push(null);
0321:            }
0322:
0323:            /**
0324:             * Reset for new run.
0325:             */
0326:            public void reset() {
0327:                releaseDTMXRTreeFrags();
0328:                // These couldn't be disposed of earlier (see comments in release()); zap them now.
0329:                if (m_rtfdtm_stack != null)
0330:                    for (java.util.Enumeration e = m_rtfdtm_stack.elements(); e
0331:                            .hasMoreElements();)
0332:                        m_dtmManager.release((DTM) e.nextElement(), true);
0333:
0334:                m_rtfdtm_stack = null; // drop our references too
0335:                m_which_rtfdtm = -1;
0336:
0337:                if (m_global_rtfdtm != null)
0338:                    m_dtmManager.release(m_global_rtfdtm, true);
0339:                m_global_rtfdtm = null;
0340:
0341:                m_dtmManager = DTMManager
0342:                        .newInstance(org.apache.xpath.objects.XMLStringFactoryImpl
0343:                                .getFactory());
0344:
0345:                m_saxLocations.removeAllElements();
0346:                m_axesIteratorStack.removeAllElements();
0347:                m_contextNodeLists.removeAllElements();
0348:                m_currentExpressionNodes.removeAllElements();
0349:                m_currentNodes.removeAllElements();
0350:                m_iteratorRoots.RemoveAllNoClear();
0351:                m_predicatePos.removeAllElements();
0352:                m_predicateRoots.RemoveAllNoClear();
0353:                m_prefixResolvers.removeAllElements();
0354:
0355:                m_prefixResolvers.push(null);
0356:                m_currentNodes.push(DTM.NULL);
0357:                m_currentExpressionNodes.push(DTM.NULL);
0358:                m_saxLocations.push(null);
0359:            }
0360:
0361:            /** The current stylesheet locator. */
0362:            ObjectStack m_saxLocations = new ObjectStack(RECURSIONLIMIT);
0363:
0364:            /**
0365:             * Set the current locater in the stylesheet.
0366:             *
0367:             * @param location The location within the stylesheet.
0368:             */
0369:            public void setSAXLocator(SourceLocator location) {
0370:                m_saxLocations.setTop(location);
0371:            }
0372:
0373:            /**
0374:             * Set the current locater in the stylesheet.
0375:             *
0376:             * @param location The location within the stylesheet.
0377:             */
0378:            public void pushSAXLocator(SourceLocator location) {
0379:                m_saxLocations.push(location);
0380:            }
0381:
0382:            /**
0383:             * Push a slot on the locations stack so that setSAXLocator can be 
0384:             * repeatedly called.
0385:             *
0386:             */
0387:            public void pushSAXLocatorNull() {
0388:                m_saxLocations.push(null);
0389:            }
0390:
0391:            /**
0392:             * Pop the current locater.
0393:             */
0394:            public void popSAXLocator() {
0395:                m_saxLocations.pop();
0396:            }
0397:
0398:            /**
0399:             * Get the current locater in the stylesheet.
0400:             *
0401:             * @return The location within the stylesheet, or null if not known.
0402:             */
0403:            public SourceLocator getSAXLocator() {
0404:                return (SourceLocator) m_saxLocations.peek();
0405:            }
0406:
0407:            /** The owner context of this XPathContext.  In the case of XSLT, this will be a
0408:             *  Transformer object.
0409:             */
0410:            private Object m_owner;
0411:
0412:            /** The owner context of this XPathContext.  In the case of XSLT, this will be a
0413:             *  Transformer object.
0414:             */
0415:            private Method m_ownerGetErrorListener;
0416:
0417:            /**
0418:             * Get the "owner" context of this context, which should be,
0419:             * in the case of XSLT, the Transformer object.  This is needed
0420:             * so that XSLT functions can get the Transformer.
0421:             * @return The owner object passed into the constructor, or null.
0422:             */
0423:            public Object getOwnerObject() {
0424:                return m_owner;
0425:            }
0426:
0427:            // ================ VarStack ===================
0428:
0429:            /**
0430:             * The stack of Variable stacks.  A VariableStack will be
0431:             * pushed onto this stack for each template invocation.
0432:             */
0433:            private VariableStack m_variableStacks = new VariableStack();
0434:
0435:            /**
0436:             * Get the variable stack, which is in charge of variables and
0437:             * parameters.
0438:             *
0439:             * @return the variable stack, which should not be null.
0440:             */
0441:            public final VariableStack getVarStack() {
0442:                return m_variableStacks;
0443:            }
0444:
0445:            /** 
0446:             * Get the variable stack, which is in charge of variables and
0447:             * parameters.
0448:             *
0449:             * @param varStack non-null reference to the variable stack.
0450:             */
0451:            public final void setVarStack(VariableStack varStack) {
0452:                m_variableStacks = varStack;
0453:            }
0454:
0455:            // ================ SourceTreeManager ===================
0456:
0457:            /** The source tree manager, which associates Source objects to source 
0458:             *  tree nodes. */
0459:            private SourceTreeManager m_sourceTreeManager = new SourceTreeManager();
0460:
0461:            /**
0462:             * Get the SourceTreeManager associated with this execution context.
0463:             *
0464:             * @return the SourceTreeManager associated with this execution context.
0465:             */
0466:            public final SourceTreeManager getSourceTreeManager() {
0467:                return m_sourceTreeManager;
0468:            }
0469:
0470:            /**
0471:             * Set the SourceTreeManager associated with this execution context.
0472:             *
0473:             * @param mgr the SourceTreeManager to be associated with this 
0474:             *        execution context.
0475:             */
0476:            public void setSourceTreeManager(SourceTreeManager mgr) {
0477:                m_sourceTreeManager = mgr;
0478:            }
0479:
0480:            // =================================================
0481:
0482:            /** The ErrorListener where errors and warnings are to be reported.   */
0483:            private ErrorListener m_errorListener;
0484:
0485:            /** A default ErrorListener in case our m_errorListener was not specified and our
0486:             *  owner either does not have an ErrorListener or has a null one.
0487:             */
0488:            private ErrorListener m_defaultErrorListener;
0489:
0490:            /**
0491:             * Get the ErrorListener where errors and warnings are to be reported.
0492:             *
0493:             * @return A non-null ErrorListener reference.
0494:             */
0495:            public final ErrorListener getErrorListener() {
0496:
0497:                if (null != m_errorListener)
0498:                    return m_errorListener;
0499:
0500:                ErrorListener retval = null;
0501:
0502:                try {
0503:                    if (null != m_ownerGetErrorListener)
0504:                        retval = (ErrorListener) m_ownerGetErrorListener
0505:                                .invoke(m_owner, new Object[] {});
0506:                } catch (Exception e) {
0507:                }
0508:
0509:                if (null == retval) {
0510:                    if (null == m_defaultErrorListener)
0511:                        m_defaultErrorListener = new org.apache.xml.utils.DefaultErrorHandler();
0512:                    retval = m_defaultErrorListener;
0513:                }
0514:
0515:                return retval;
0516:            }
0517:
0518:            /**
0519:             * Set the ErrorListener where errors and warnings are to be reported.
0520:             *
0521:             * @param listener A non-null ErrorListener reference.
0522:             */
0523:            public void setErrorListener(ErrorListener listener)
0524:                    throws IllegalArgumentException {
0525:                if (listener == null)
0526:                    throw new IllegalArgumentException(XSLMessages
0527:                            .createXPATHMessage(
0528:                                    XPATHErrorResources.ER_NULL_ERROR_HANDLER,
0529:                                    null)); //"Null error handler");
0530:                m_errorListener = listener;
0531:            }
0532:
0533:            // =================================================
0534:
0535:            /** The TrAX URI Resolver for resolving URIs from the document(...)
0536:             *  function to source tree nodes.  */
0537:            private URIResolver m_uriResolver;
0538:
0539:            /**
0540:             * Get the URIResolver associated with this execution context.
0541:             *
0542:             * @return a URI resolver, which may be null.
0543:             */
0544:            public final URIResolver getURIResolver() {
0545:                return m_uriResolver;
0546:            }
0547:
0548:            /**
0549:             * Set the URIResolver associated with this execution context.
0550:             *
0551:             * @param resolver the URIResolver to be associated with this 
0552:             *        execution context, may be null to clear an already set resolver.
0553:             */
0554:            public void setURIResolver(URIResolver resolver) {
0555:                m_uriResolver = resolver;
0556:            }
0557:
0558:            // =================================================
0559:
0560:            /** The reader of the primary source tree.    */
0561:            public XMLReader m_primaryReader;
0562:
0563:            /**
0564:             * Get primary XMLReader associated with this execution context.
0565:             *
0566:             * @return The reader of the primary source tree.
0567:             */
0568:            public final XMLReader getPrimaryReader() {
0569:                return m_primaryReader;
0570:            }
0571:
0572:            /**
0573:             * Set primary XMLReader associated with this execution context.
0574:             *
0575:             * @param reader The reader of the primary source tree.
0576:             */
0577:            public void setPrimaryReader(XMLReader reader) {
0578:                m_primaryReader = reader;
0579:            }
0580:
0581:            // =================================================
0582:
0583:            /** Misnamed string manager for XPath messages.  */
0584:            // private static XSLMessages m_XSLMessages = new XSLMessages();
0585:            /**
0586:             * Tell the user of an assertion error, and probably throw an
0587:             * exception.
0588:             *
0589:             * @param b  If false, a TransformerException will be thrown.
0590:             * @param msg The assertion message, which should be informative.
0591:             * 
0592:             * @throws javax.xml.transform.TransformerException if b is false.
0593:             */
0594:            private void assertion(boolean b, String msg)
0595:                    throws javax.xml.transform.TransformerException {
0596:                if (!b) {
0597:                    ErrorListener errorHandler = getErrorListener();
0598:
0599:                    if (errorHandler != null) {
0600:                        errorHandler
0601:                                .fatalError(new TransformerException(
0602:                                        XSLMessages
0603:                                                .createMessage(
0604:                                                        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
0605:                                                        new Object[] { msg }),
0606:                                        (SAXSourceLocator) this .getSAXLocator()));
0607:                    }
0608:                }
0609:            }
0610:
0611:            //==========================================================
0612:            // SECTION: Execution context state tracking
0613:            //==========================================================
0614:
0615:            /**
0616:             * The current context node list.
0617:             */
0618:            private Stack m_contextNodeLists = new Stack();
0619:
0620:            public Stack getContextNodeListsStack() {
0621:                return m_contextNodeLists;
0622:            }
0623:
0624:            public void setContextNodeListsStack(Stack s) {
0625:                m_contextNodeLists = s;
0626:            }
0627:
0628:            /**
0629:             * Get the current context node list.
0630:             *
0631:             * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
0632:             * also refered to here as a <term>context node list</term>.
0633:             */
0634:            public final DTMIterator getContextNodeList() {
0635:
0636:                if (m_contextNodeLists.size() > 0)
0637:                    return (DTMIterator) m_contextNodeLists.peek();
0638:                else
0639:                    return null;
0640:            }
0641:
0642:            /**
0643:             * Set the current context node list.
0644:             *
0645:             * @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
0646:             * also refered to here as a <term>context node list</term>.
0647:             * @xsl.usage internal
0648:             */
0649:            public final void pushContextNodeList(DTMIterator nl) {
0650:                m_contextNodeLists.push(nl);
0651:            }
0652:
0653:            /**
0654:             * Pop the current context node list.
0655:             * @xsl.usage internal
0656:             */
0657:            public final void popContextNodeList() {
0658:                if (m_contextNodeLists.isEmpty())
0659:                    System.err
0660:                            .println("Warning: popContextNodeList when stack is empty!");
0661:                else
0662:                    m_contextNodeLists.pop();
0663:            }
0664:
0665:            /**
0666:             * The ammount to use for stacks that record information during the 
0667:             * recursive execution.
0668:             */
0669:            public static final int RECURSIONLIMIT = (1024 * 4);
0670:
0671:            /** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
0672:             *  Not to be confused with the current node list.  %REVIEW% Note that there 
0673:             *  are no bounds check and resize for this stack, so if it is blown, it's all 
0674:             *  over.  */
0675:            private IntStack m_currentNodes = new IntStack(RECURSIONLIMIT);
0676:
0677:            //  private NodeVector m_currentNodes = new NodeVector();
0678:
0679:            public IntStack getCurrentNodeStack() {
0680:                return m_currentNodes;
0681:            }
0682:
0683:            public void setCurrentNodeStack(IntStack nv) {
0684:                m_currentNodes = nv;
0685:            }
0686:
0687:            /**
0688:             * Get the current context node.
0689:             *
0690:             * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
0691:             */
0692:            public final int getCurrentNode() {
0693:                return m_currentNodes.peek();
0694:            }
0695:
0696:            /**
0697:             * Set the current context node and expression node.
0698:             *
0699:             * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
0700:             * @param en the sub-expression context node.
0701:             */
0702:            public final void pushCurrentNodeAndExpression(int cn, int en) {
0703:                m_currentNodes.push(cn);
0704:                m_currentExpressionNodes.push(cn);
0705:            }
0706:
0707:            /**
0708:             * Set the current context node.
0709:             */
0710:            public final void popCurrentNodeAndExpression() {
0711:                m_currentNodes.quickPop(1);
0712:                m_currentExpressionNodes.quickPop(1);
0713:            }
0714:
0715:            /**
0716:             * Push the current context node, expression node, and prefix resolver.
0717:             *
0718:             * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
0719:             * @param en the sub-expression context node.
0720:             * @param nc the namespace context (prefix resolver.
0721:             */
0722:            public final void pushExpressionState(int cn, int en,
0723:                    PrefixResolver nc) {
0724:                m_currentNodes.push(cn);
0725:                m_currentExpressionNodes.push(cn);
0726:                m_prefixResolvers.push(nc);
0727:            }
0728:
0729:            /**
0730:             * Pop the current context node, expression node, and prefix resolver.
0731:             */
0732:            public final void popExpressionState() {
0733:                m_currentNodes.quickPop(1);
0734:                m_currentExpressionNodes.quickPop(1);
0735:                m_prefixResolvers.pop();
0736:            }
0737:
0738:            /**
0739:             * Set the current context node.
0740:             *
0741:             * @param n the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
0742:             */
0743:            public final void pushCurrentNode(int n) {
0744:                m_currentNodes.push(n);
0745:            }
0746:
0747:            /**
0748:             * Pop the current context node.
0749:             */
0750:            public final void popCurrentNode() {
0751:                m_currentNodes.quickPop(1);
0752:            }
0753:
0754:            /**
0755:             * Set the current predicate root.
0756:             */
0757:            public final void pushPredicateRoot(int n) {
0758:                m_predicateRoots.push(n);
0759:            }
0760:
0761:            /**
0762:             * Pop the current predicate root.
0763:             */
0764:            public final void popPredicateRoot() {
0765:                m_predicateRoots.popQuick();
0766:            }
0767:
0768:            /**
0769:             * Get the current predicate root.
0770:             */
0771:            public final int getPredicateRoot() {
0772:                return m_predicateRoots.peepOrNull();
0773:            }
0774:
0775:            /**
0776:             * Set the current location path iterator root.
0777:             */
0778:            public final void pushIteratorRoot(int n) {
0779:                m_iteratorRoots.push(n);
0780:            }
0781:
0782:            /**
0783:             * Pop the current location path iterator root.
0784:             */
0785:            public final void popIteratorRoot() {
0786:                m_iteratorRoots.popQuick();
0787:            }
0788:
0789:            /**
0790:             * Get the current location path iterator root.
0791:             */
0792:            public final int getIteratorRoot() {
0793:                return m_iteratorRoots.peepOrNull();
0794:            }
0795:
0796:            /** A stack of the current sub-expression nodes.  */
0797:            private NodeVector m_iteratorRoots = new NodeVector();
0798:
0799:            /** A stack of the current sub-expression nodes.  */
0800:            private NodeVector m_predicateRoots = new NodeVector();
0801:
0802:            /** A stack of the current sub-expression nodes.  */
0803:            private IntStack m_currentExpressionNodes = new IntStack(
0804:                    RECURSIONLIMIT);
0805:
0806:            public IntStack getCurrentExpressionNodeStack() {
0807:                return m_currentExpressionNodes;
0808:            }
0809:
0810:            public void setCurrentExpressionNodeStack(IntStack nv) {
0811:                m_currentExpressionNodes = nv;
0812:            }
0813:
0814:            private IntStack m_predicatePos = new IntStack();
0815:
0816:            public final int getPredicatePos() {
0817:                return m_predicatePos.peek();
0818:            }
0819:
0820:            public final void pushPredicatePos(int n) {
0821:                m_predicatePos.push(n);
0822:            }
0823:
0824:            public final void popPredicatePos() {
0825:                m_predicatePos.pop();
0826:            }
0827:
0828:            /**
0829:             * Get the current node that is the expression's context (i.e. for current() support).
0830:             *
0831:             * @return The current sub-expression node.
0832:             */
0833:            public final int getCurrentExpressionNode() {
0834:                return m_currentExpressionNodes.peek();
0835:            }
0836:
0837:            /**
0838:             * Set the current node that is the expression's context (i.e. for current() support).
0839:             *
0840:             * @param n The sub-expression node to be current.
0841:             */
0842:            public final void pushCurrentExpressionNode(int n) {
0843:                m_currentExpressionNodes.push(n);
0844:            }
0845:
0846:            /**
0847:             * Pop the current node that is the expression's context 
0848:             * (i.e. for current() support).
0849:             */
0850:            public final void popCurrentExpressionNode() {
0851:                m_currentExpressionNodes.quickPop(1);
0852:            }
0853:
0854:            private ObjectStack m_prefixResolvers = new ObjectStack(
0855:                    RECURSIONLIMIT);
0856:
0857:            /**
0858:             * Get the current namespace context for the xpath.
0859:             *
0860:             * @return the current prefix resolver for resolving prefixes to 
0861:             *         namespace URLs.
0862:             */
0863:            public final PrefixResolver getNamespaceContext() {
0864:                return (PrefixResolver) m_prefixResolvers.peek();
0865:            }
0866:
0867:            /**
0868:             * Get the current namespace context for the xpath.
0869:             *
0870:             * @param pr the prefix resolver to be used for resolving prefixes to 
0871:             *         namespace URLs.
0872:             */
0873:            public final void setNamespaceContext(PrefixResolver pr) {
0874:                m_prefixResolvers.setTop(pr);
0875:            }
0876:
0877:            /**
0878:             * Push a current namespace context for the xpath.
0879:             *
0880:             * @param pr the prefix resolver to be used for resolving prefixes to 
0881:             *         namespace URLs.
0882:             */
0883:            public final void pushNamespaceContext(PrefixResolver pr) {
0884:                m_prefixResolvers.push(pr);
0885:            }
0886:
0887:            /**
0888:             * Just increment the namespace contest stack, so that setNamespaceContext
0889:             * can be used on the slot.
0890:             */
0891:            public final void pushNamespaceContextNull() {
0892:                m_prefixResolvers.push(null);
0893:            }
0894:
0895:            /**
0896:             * Pop the current namespace context for the xpath.
0897:             */
0898:            public final void popNamespaceContext() {
0899:                m_prefixResolvers.pop();
0900:            }
0901:
0902:            //==========================================================
0903:            // SECTION: Current TreeWalker contexts (for internal use)
0904:            //==========================================================
0905:
0906:            /**
0907:             * Stack of AxesIterators.
0908:             */
0909:            private Stack m_axesIteratorStack = new Stack();
0910:
0911:            public Stack getAxesIteratorStackStacks() {
0912:                return m_axesIteratorStack;
0913:            }
0914:
0915:            public void setAxesIteratorStackStacks(Stack s) {
0916:                m_axesIteratorStack = s;
0917:            }
0918:
0919:            /**
0920:             * Push a TreeWalker on the stack.
0921:             *
0922:             * @param iter A sub-context AxesWalker.
0923:             * @xsl.usage internal
0924:             */
0925:            public final void pushSubContextList(SubContextList iter) {
0926:                m_axesIteratorStack.push(iter);
0927:            }
0928:
0929:            /**
0930:             * Pop the last pushed axes iterator.
0931:             * @xsl.usage internal
0932:             */
0933:            public final void popSubContextList() {
0934:                m_axesIteratorStack.pop();
0935:            }
0936:
0937:            /**
0938:             * Get the current axes iterator, or return null if none.
0939:             *
0940:             * @return the sub-context node list.
0941:             * @xsl.usage internal
0942:             */
0943:            public SubContextList getSubContextList() {
0944:                return m_axesIteratorStack.isEmpty() ? null
0945:                        : (SubContextList) m_axesIteratorStack.peek();
0946:            }
0947:
0948:            /**
0949:             * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a> 
0950:             * as defined by the XSLT spec.
0951:             *
0952:             * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>.
0953:             * @xsl.usage internal
0954:             */
0955:
0956:            public org.apache.xpath.axes.SubContextList getCurrentNodeList() {
0957:                return m_axesIteratorStack.isEmpty() ? null
0958:                        : (SubContextList) m_axesIteratorStack.elementAt(0);
0959:            }
0960:
0961:            //==========================================================
0962:            // SECTION: Implementation of ExpressionContext interface
0963:            //==========================================================
0964:
0965:            /**
0966:             * Get the current context node.
0967:             * @return The current context node.
0968:             */
0969:            public final int getContextNode() {
0970:                return this .getCurrentNode();
0971:            }
0972:
0973:            /**
0974:             * Get the current context node list.
0975:             * @return An iterator for the current context list, as
0976:             * defined in XSLT.
0977:             */
0978:            public final DTMIterator getContextNodes() {
0979:
0980:                try {
0981:                    DTMIterator cnl = getContextNodeList();
0982:
0983:                    if (null != cnl)
0984:                        return cnl.cloneWithReset();
0985:                    else
0986:                        return null; // for now... this might ought to be an empty iterator.
0987:                } catch (CloneNotSupportedException cnse) {
0988:                    return null; // error reporting?
0989:                }
0990:            }
0991:
0992:            XPathExpressionContext expressionContext = new XPathExpressionContext();
0993:
0994:            /**
0995:             * The the expression context for extensions for this context.
0996:             * 
0997:             * @return An object that implements the ExpressionContext.
0998:             */
0999:            public ExpressionContext getExpressionContext() {
1000:                return expressionContext;
1001:            }
1002:
1003:            public class XPathExpressionContext implements  ExpressionContext {
1004:                /**
1005:                 * Return the XPathContext associated with this XPathExpressionContext.
1006:                 * Extensions should use this judiciously and only when special processing
1007:                 * requirements cannot be met another way.  Consider requesting an enhancement
1008:                 * to the ExpressionContext interface to avoid having to call this method.
1009:                 * @return the XPathContext associated with this XPathExpressionContext.
1010:                 */
1011:                public XPathContext getXPathContext() {
1012:                    return XPathContext.this ;
1013:                }
1014:
1015:                /**
1016:                 * Return the DTMManager object.  Though XPathContext context extends 
1017:                 * the DTMManager, it really is a proxy for the real DTMManager.  If a 
1018:                 * caller needs to make a lot of calls to the DTMManager, it is faster 
1019:                 * if it gets the real one from this function.
1020:                 */
1021:                public DTMManager getDTMManager() {
1022:                    return m_dtmManager;
1023:                }
1024:
1025:                /**
1026:                 * Get the current context node.
1027:                 * @return The current context node.
1028:                 */
1029:                public org.w3c.dom.Node getContextNode() {
1030:                    int context = getCurrentNode();
1031:
1032:                    return getDTM(context).getNode(context);
1033:                }
1034:
1035:                /**
1036:                 * Get the current context node list.
1037:                 * @return An iterator for the current context list, as
1038:                 * defined in XSLT.
1039:                 */
1040:                public org.w3c.dom.traversal.NodeIterator getContextNodes() {
1041:                    return new org.apache.xml.dtm.ref.DTMNodeIterator(
1042:                            getContextNodeList());
1043:                }
1044:
1045:                /**
1046:                 * Get the error listener.
1047:                 * @return The registered error listener.
1048:                 */
1049:                public ErrorListener getErrorListener() {
1050:                    return XPathContext.this .getErrorListener();
1051:                }
1052:
1053:                /**
1054:                 * Get the value of a node as a number.
1055:                 * @param n Node to be converted to a number.  May be null.
1056:                 * @return value of n as a number.
1057:                 */
1058:                public double toNumber(org.w3c.dom.Node n) {
1059:                    // %REVIEW% You can't get much uglier than this...
1060:                    int nodeHandle = getDTMHandleFromNode(n);
1061:                    DTM dtm = getDTM(nodeHandle);
1062:                    XString xobj = (XString) dtm.getStringValue(nodeHandle);
1063:                    return xobj.num();
1064:                }
1065:
1066:                /**
1067:                 * Get the value of a node as a string.
1068:                 * @param n Node to be converted to a string.  May be null.
1069:                 * @return value of n as a string, or an empty string if n is null.
1070:                 */
1071:                public String toString(org.w3c.dom.Node n) {
1072:                    // %REVIEW% You can't get much uglier than this...
1073:                    int nodeHandle = getDTMHandleFromNode(n);
1074:                    DTM dtm = getDTM(nodeHandle);
1075:                    XMLString strVal = dtm.getStringValue(nodeHandle);
1076:                    return strVal.toString();
1077:                }
1078:
1079:                /**
1080:                 * Get a variable based on it's qualified name.
1081:                 * @param qname The qualified name of the variable.
1082:                 * @return The evaluated value of the variable.
1083:                 * @throws javax.xml.transform.TransformerException
1084:                 */
1085:
1086:                public final XObject getVariableOrParam(
1087:                        org.apache.xml.utils.QName qname)
1088:                        throws javax.xml.transform.TransformerException {
1089:                    return m_variableStacks.getVariableOrParam(
1090:                            XPathContext.this , qname);
1091:                }
1092:
1093:            }
1094:
1095:            /**
1096:             * Get a DTM to be used as a container for a global Result Tree
1097:             * Fragment. This will always be an instance of (derived from? equivalent to?) 
1098:             * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX 
1099:             * output to it. It may be a single DTM containing for multiple fragments, 
1100:             * if the implementation supports that.
1101:             * 
1102:             * Note: The distinction between this method and getRTFDTM() is that the latter
1103:             * allocates space from the dynamic variable stack (m_rtfdtm_stack), which may
1104:             * be pruned away again as the templates which defined those variables are exited.
1105:             * Global variables may be bound late (see XUnresolvedVariable), and never want to
1106:             * be discarded, hence we need to allocate them separately and don't actually need
1107:             * a stack to track them.
1108:             * 
1109:             * @return a non-null DTM reference.
1110:             */
1111:            public DTM getGlobalRTFDTM() {
1112:                // We probably should _NOT_ be applying whitespace filtering at this stage!
1113:                //
1114:                // Some magic has been applied in DTMManagerDefault to recognize this set of options
1115:                // and generate an instance of DTM which can contain multiple documents
1116:                // (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
1117:                // I didn't want to change the manager API at this time, or expose 
1118:                // too many dependencies on its internals. (Ideally, I'd like to move
1119:                // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
1120:                // specify the subclass here.)
1121:
1122:                // If it doesn't exist, or if the one already existing is in the middle of
1123:                // being constructed, we need to obtain a new DTM to write into. I'm not sure
1124:                // the latter will ever arise, but I'd rather be just a bit paranoid..
1125:                if (m_global_rtfdtm == null
1126:                        || m_global_rtfdtm.isTreeIncomplete()) {
1127:                    m_global_rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null,
1128:                            true, null, false, false);
1129:                }
1130:                return m_global_rtfdtm;
1131:            }
1132:
1133:            /**
1134:             * Get a DTM to be used as a container for a dynamic Result Tree
1135:             * Fragment. This will always be an instance of (derived from? equivalent to?) 
1136:             * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX 
1137:             * output to it. It may be a single DTM containing for multiple fragments, 
1138:             * if the implementation supports that.
1139:             * 
1140:             * @return a non-null DTM reference.
1141:             */
1142:            public DTM getRTFDTM() {
1143:                SAX2RTFDTM rtfdtm;
1144:
1145:                // We probably should _NOT_ be applying whitespace filtering at this stage!
1146:                //
1147:                // Some magic has been applied in DTMManagerDefault to recognize this set of options
1148:                // and generate an instance of DTM which can contain multiple documents
1149:                // (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
1150:                // I didn't want to change the manager API at this time, or expose 
1151:                // too many dependencies on its internals. (Ideally, I'd like to move
1152:                // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
1153:                // specify the subclass here.)
1154:
1155:                if (m_rtfdtm_stack == null) {
1156:                    m_rtfdtm_stack = new Vector();
1157:                    rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null, true, null,
1158:                            false, false);
1159:                    m_rtfdtm_stack.addElement(rtfdtm);
1160:                    ++m_which_rtfdtm;
1161:                } else if (m_which_rtfdtm < 0) {
1162:                    rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack
1163:                            .elementAt(++m_which_rtfdtm);
1164:                } else {
1165:                    rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack
1166:                            .elementAt(m_which_rtfdtm);
1167:
1168:                    // It might already be under construction -- the classic example would be
1169:                    // an xsl:variable which uses xsl:call-template as part of its value. To
1170:                    // handle this recursion, we have to start a new RTF DTM, pushing the old
1171:                    // one onto a stack so we can return to it. This is not as uncommon a case
1172:                    // as we might wish, unfortunately, as some folks insist on coding XSLT
1173:                    // as if it were a procedural language...
1174:                    if (rtfdtm.isTreeIncomplete()) {
1175:                        if (++m_which_rtfdtm < m_rtfdtm_stack.size())
1176:                            rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack
1177:                                    .elementAt(m_which_rtfdtm);
1178:                        else {
1179:                            rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null,
1180:                                    true, null, false, false);
1181:                            m_rtfdtm_stack.addElement(rtfdtm);
1182:                        }
1183:                    }
1184:                }
1185:
1186:                return rtfdtm;
1187:            }
1188:
1189:            /** Push the RTFDTM's context mark, to allows discarding RTFs added after this
1190:             * point. (If it doesn't exist we don't push, since we might still be able to 
1191:             * get away with not creating it. That requires that excessive pops be harmless.)
1192:             * */
1193:            public void pushRTFContext() {
1194:                m_last_pushed_rtfdtm.push(m_which_rtfdtm);
1195:                if (null != m_rtfdtm_stack)
1196:                    ((SAX2RTFDTM) (getRTFDTM())).pushRewindMark();
1197:            }
1198:
1199:            /** Pop the RTFDTM's context mark. This discards any RTFs added after the last
1200:             * mark was set. 
1201:             * 
1202:             * If there is no RTF DTM, there's nothing to pop so this
1203:             * becomes a no-op. If pushes were issued before this was called, we count on
1204:             * the fact that popRewindMark is defined such that overpopping just resets
1205:             * to empty.
1206:             * 
1207:             * Complicating factor: We need to handle the case of popping back to a previous
1208:             * RTF DTM, if one of the weird produce-an-RTF-to-build-an-RTF cases arose.
1209:             * Basically: If pop says this DTM is now empty, then return to the previous
1210:             * if one exists, in whatever state we left it in. UGLY, but hopefully the
1211:             * situation which forces us to consider this will arise exceedingly rarely.
1212:             * */
1213:            public void popRTFContext() {
1214:                int previous = m_last_pushed_rtfdtm.pop();
1215:                if (null == m_rtfdtm_stack)
1216:                    return;
1217:
1218:                if (m_which_rtfdtm == previous) {
1219:                    if (previous >= 0) // guard against none-active
1220:                    {
1221:                        boolean isEmpty = ((SAX2RTFDTM) (m_rtfdtm_stack
1222:                                .elementAt(previous))).popRewindMark();
1223:                    }
1224:                } else
1225:                    while (m_which_rtfdtm != previous) {
1226:                        // Empty each DTM before popping, so it's ready for reuse
1227:                        // _DON'T_ pop the previous, since it's still open (which is why we
1228:                        // stacked up more of these) and did not receive a mark.
1229:                        boolean isEmpty = ((SAX2RTFDTM) (m_rtfdtm_stack
1230:                                .elementAt(m_which_rtfdtm))).popRewindMark();
1231:                        --m_which_rtfdtm;
1232:                    }
1233:            }
1234:
1235:            /**
1236:             * Gets DTMXRTreeFrag object if one has already been created.
1237:             * Creates new DTMXRTreeFrag object and adds to m_DTMXRTreeFrags  HashMap,
1238:             * otherwise.  
1239:             * @param dtmIdentity
1240:             * @return DTMXRTreeFrag
1241:             */
1242:            public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity) {
1243:                if (m_DTMXRTreeFrags == null) {
1244:                    m_DTMXRTreeFrags = new HashMap();
1245:                }
1246:
1247:                if (m_DTMXRTreeFrags.containsKey(new Integer(dtmIdentity))) {
1248:                    return (DTMXRTreeFrag) m_DTMXRTreeFrags.get(new Integer(
1249:                            dtmIdentity));
1250:                } else {
1251:                    final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,
1252:                            this );
1253:                    m_DTMXRTreeFrags.put(new Integer(dtmIdentity), frag);
1254:                    return frag;
1255:                }
1256:            }
1257:
1258:            /**
1259:             * Cleans DTMXRTreeFrag objects by removing references 
1260:             * to DTM and XPathContext objects.   
1261:             */
1262:            private final void releaseDTMXRTreeFrags() {
1263:                if (m_DTMXRTreeFrags == null) {
1264:                    return;
1265:                }
1266:                final Iterator iter = (m_DTMXRTreeFrags.values()).iterator();
1267:                while (iter.hasNext()) {
1268:                    DTMXRTreeFrag frag = (DTMXRTreeFrag) iter.next();
1269:                    frag.destruct();
1270:                    iter.remove();
1271:                }
1272:                m_DTMXRTreeFrags = null;
1273:            }
1274:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.