Source Code Cross Referenced for StepPattern.java in  » XML » xalan » org » apache » xpath » patterns » 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.patterns 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1999-2004 The Apache Software Foundation.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        /*
017:         * $Id: StepPattern.java,v 1.31 2005/01/23 01:08:22 mcnamara Exp $
018:         */
019:        package org.apache.xpath.patterns;
020:
021:        import org.apache.xml.dtm.Axis;
022:        import org.apache.xml.dtm.DTM;
023:        import org.apache.xml.dtm.DTMAxisTraverser;
024:        import org.apache.xml.dtm.DTMFilter;
025:        import org.apache.xpath.Expression;
026:        import org.apache.xpath.ExpressionOwner;
027:        import org.apache.xpath.XPathContext;
028:        import org.apache.xpath.XPathVisitor;
029:        import org.apache.xpath.axes.SubContextList;
030:        import org.apache.xpath.compiler.PsuedoNames;
031:        import org.apache.xpath.objects.XObject;
032:
033:        /**
034:         * This class represents a single pattern match step.
035:         * @xsl.usage advanced
036:         */
037:        public class StepPattern extends NodeTest implements  SubContextList,
038:                ExpressionOwner {
039:            static final long serialVersionUID = 9071668960168152644L;
040:
041:            /** The axis for this test. */
042:            protected int m_axis;
043:
044:            /**
045:             * Construct a StepPattern that tests for namespaces and node names.
046:             *
047:             *
048:             * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
049:             * @param namespace The namespace to be tested.
050:             * @param name The local name to be tested.
051:             * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
052:             * @param axisForPredicate No longer used.
053:             */
054:            public StepPattern(int whatToShow, String namespace, String name,
055:                    int axis, int axisForPredicate) {
056:
057:                super (whatToShow, namespace, name);
058:
059:                m_axis = axis;
060:            }
061:
062:            /**
063:             * Construct a StepPattern that doesn't test for node names.
064:             *
065:             *
066:             * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
067:             * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
068:             * @param axisForPredicate No longer used.
069:             */
070:            public StepPattern(int whatToShow, int axis, int axisForPredicate) {
071:
072:                super (whatToShow);
073:
074:                m_axis = axis;
075:            }
076:
077:            /**
078:             * The target local name or psuedo name, for hash table lookup optimization.
079:             *  @serial
080:             */
081:            String m_targetString; // only calculate on head
082:
083:            /**
084:             * Calculate the local name or psuedo name of the node that this pattern will test,
085:             * for hash table lookup optimization.
086:             *
087:             * @see org.apache.xpath.compiler.PsuedoNames
088:             */
089:            public void calcTargetString() {
090:
091:                int whatToShow = getWhatToShow();
092:
093:                switch (whatToShow) {
094:                case DTMFilter.SHOW_COMMENT:
095:                    m_targetString = PsuedoNames.PSEUDONAME_COMMENT;
096:                    break;
097:                case DTMFilter.SHOW_TEXT:
098:                case DTMFilter.SHOW_CDATA_SECTION:
099:                case (DTMFilter.SHOW_TEXT | DTMFilter.SHOW_CDATA_SECTION):
100:                    m_targetString = PsuedoNames.PSEUDONAME_TEXT;
101:                    break;
102:                case DTMFilter.SHOW_ALL:
103:                    m_targetString = PsuedoNames.PSEUDONAME_ANY;
104:                    break;
105:                case DTMFilter.SHOW_DOCUMENT:
106:                case DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT:
107:                    m_targetString = PsuedoNames.PSEUDONAME_ROOT;
108:                    break;
109:                case DTMFilter.SHOW_ELEMENT:
110:                    if (this .WILD == m_name)
111:                        m_targetString = PsuedoNames.PSEUDONAME_ANY;
112:                    else
113:                        m_targetString = m_name;
114:                    break;
115:                default:
116:                    m_targetString = PsuedoNames.PSEUDONAME_ANY;
117:                    break;
118:                }
119:            }
120:
121:            /**
122:             * Get the local name or psuedo name of the node that this pattern will test,
123:             * for hash table lookup optimization.
124:             *
125:             *
126:             * @return local name or psuedo name of the node.
127:             * @see org.apache.xpath.compiler.PsuedoNames
128:             */
129:            public String getTargetString() {
130:                return m_targetString;
131:            }
132:
133:            /**
134:             * Reference to nodetest and predicate for
135:             * parent or ancestor.
136:             * @serial
137:             */
138:            StepPattern m_relativePathPattern;
139:
140:            /**
141:             * This function is used to fixup variables from QNames to stack frame
142:             * indexes at stylesheet build time.
143:             * @param vars List of QNames that correspond to variables.  This list
144:             * should be searched backwards for the first qualified name that
145:             * corresponds to the variable reference qname.  The position of the
146:             * QName in the vector from the start of the vector will be its position
147:             * in the stack frame (but variables above the globalsTop value will need
148:             * to be offset to the current stack frame).
149:             * @param globalsSize The number of variables in the global variable area.
150:             */
151:            public void fixupVariables(java.util.Vector vars, int globalsSize) {
152:
153:                super .fixupVariables(vars, globalsSize);
154:
155:                if (null != m_predicates) {
156:                    for (int i = 0; i < m_predicates.length; i++) {
157:                        m_predicates[i].fixupVariables(vars, globalsSize);
158:                    }
159:                }
160:
161:                if (null != m_relativePathPattern) {
162:                    m_relativePathPattern.fixupVariables(vars, globalsSize);
163:                }
164:            }
165:
166:            /**
167:             * Set the reference to nodetest and predicate for
168:             * parent or ancestor.
169:             *
170:             *
171:             * @param expr The relative pattern expression.
172:             */
173:            public void setRelativePathPattern(StepPattern expr) {
174:
175:                m_relativePathPattern = expr;
176:                expr.exprSetParent(this );
177:
178:                calcScore();
179:            }
180:
181:            /**
182:             * Get the reference to nodetest and predicate for
183:             * parent or ancestor.
184:             *
185:             *
186:             * @return The relative pattern expression.
187:             */
188:            public StepPattern getRelativePathPattern() {
189:                return m_relativePathPattern;
190:            }
191:
192:            //  /**
193:            //   * Set the list of predicate expressions for this pattern step.
194:            //   * @param predicates List of expression objects.
195:            //   */
196:            //  public void setPredicates(Expression[] predicates)
197:            //  {
198:            //    m_predicates = predicates;
199:            //  }
200:
201:            /**
202:             * Set the list of predicate expressions for this pattern step.
203:             * @return List of expression objects.
204:             */
205:            public Expression[] getPredicates() {
206:                return m_predicates;
207:            }
208:
209:            /**
210:             * The list of predicate expressions for this pattern step.
211:             *  @serial
212:             */
213:            Expression[] m_predicates;
214:
215:            /**
216:             * Tell if this expression or it's subexpressions can traverse outside
217:             * the current subtree.
218:             *
219:             * NOTE: Ancestors tests with predicates are problematic, and will require
220:             * special treatment.
221:             *
222:             * @return true if traversal outside the context node's subtree can occur.
223:             */
224:            public boolean canTraverseOutsideSubtree() {
225:
226:                int n = getPredicateCount();
227:
228:                for (int i = 0; i < n; i++) {
229:                    if (getPredicate(i).canTraverseOutsideSubtree())
230:                        return true;
231:                }
232:
233:                return false;
234:            }
235:
236:            /**
237:             * Get a predicate expression.
238:             *
239:             *
240:             * @param i The index of the predicate.
241:             *
242:             * @return A predicate expression.
243:             */
244:            public Expression getPredicate(int i) {
245:                return m_predicates[i];
246:            }
247:
248:            /**
249:             * Get the number of predicates for this match pattern step.
250:             *
251:             *
252:             * @return the number of predicates for this match pattern step.
253:             */
254:            public final int getPredicateCount() {
255:                return (null == m_predicates) ? 0 : m_predicates.length;
256:            }
257:
258:            /**
259:             * Set the predicates for this match pattern step.
260:             *
261:             *
262:             * @param predicates An array of expressions that define predicates
263:             *                   for this step.
264:             */
265:            public void setPredicates(Expression[] predicates) {
266:
267:                m_predicates = predicates;
268:                if (null != predicates) {
269:                    for (int i = 0; i < predicates.length; i++) {
270:                        predicates[i].exprSetParent(this );
271:                    }
272:                }
273:
274:                calcScore();
275:            }
276:
277:            /**
278:             * Static calc of match score.
279:             */
280:            public void calcScore() {
281:
282:                if ((getPredicateCount() > 0)
283:                        || (null != m_relativePathPattern)) {
284:                    m_score = SCORE_OTHER;
285:                } else
286:                    super .calcScore();
287:
288:                if (null == m_targetString)
289:                    calcTargetString();
290:            }
291:
292:            /**
293:             * Execute this pattern step, including predicates.
294:             *
295:             *
296:             * @param xctxt XPath runtime context.
297:             * @param currentNode The current node context.
298:             *
299:             * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
300:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
301:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
302:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
303:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
304:             *
305:             * @throws javax.xml.transform.TransformerException
306:             */
307:            public XObject execute(XPathContext xctxt, int currentNode)
308:                    throws javax.xml.transform.TransformerException {
309:
310:                DTM dtm = xctxt.getDTM(currentNode);
311:
312:                if (dtm != null) {
313:                    int expType = dtm.getExpandedTypeID(currentNode);
314:
315:                    return execute(xctxt, currentNode, dtm, expType);
316:                }
317:
318:                return NodeTest.SCORE_NONE;
319:            }
320:
321:            /**
322:             * Execute this pattern step, including predicates.
323:             *
324:             *
325:             * @param xctxt XPath runtime context.
326:             *
327:             * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
328:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
329:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
330:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
331:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
332:             *
333:             * @throws javax.xml.transform.TransformerException
334:             */
335:            public XObject execute(XPathContext xctxt)
336:                    throws javax.xml.transform.TransformerException {
337:                return execute(xctxt, xctxt.getCurrentNode());
338:            }
339:
340:            /**
341:             * Execute an expression in the XPath runtime context, and return the
342:             * result of the expression.
343:             *
344:             *
345:             * @param xctxt The XPath runtime context.
346:             * @param currentNode The currentNode.
347:             * @param dtm The DTM of the current node.
348:             * @param expType The expanded type ID of the current node.
349:             *
350:             * @return The result of the expression in the form of a <code>XObject</code>.
351:             *
352:             * @throws javax.xml.transform.TransformerException if a runtime exception
353:             *         occurs.
354:             */
355:            public XObject execute(XPathContext xctxt, int currentNode,
356:                    DTM dtm, int expType)
357:                    throws javax.xml.transform.TransformerException {
358:
359:                if (m_whatToShow == NodeTest.SHOW_BYFUNCTION) {
360:                    if (null != m_relativePathPattern) {
361:                        return m_relativePathPattern.execute(xctxt);
362:                    } else
363:                        return NodeTest.SCORE_NONE;
364:                }
365:
366:                XObject score;
367:
368:                score = super .execute(xctxt, currentNode, dtm, expType);
369:
370:                if (score == NodeTest.SCORE_NONE)
371:                    return NodeTest.SCORE_NONE;
372:
373:                if (getPredicateCount() != 0) {
374:                    if (!executePredicates(xctxt, dtm, currentNode))
375:                        return NodeTest.SCORE_NONE;
376:                }
377:
378:                if (null != m_relativePathPattern)
379:                    return m_relativePathPattern.executeRelativePathPattern(
380:                            xctxt, dtm, currentNode);
381:
382:                return score;
383:            }
384:
385:            /**
386:             * New Method to check whether the current node satisfies a position predicate
387:             *
388:             * @param xctxt The XPath runtime context.
389:             * @param predPos Which predicate we're evaluating of foo[1][2][3].
390:             * @param dtm The DTM of the current node.
391:             * @param context The currentNode.
392:             * @param pos The position being requested, i.e. the value returned by 
393:             *            m_predicates[predPos].execute(xctxt).
394:             *
395:             * @return true of the position of the context matches pos, false otherwise.
396:             */
397:            private final boolean checkProximityPosition(XPathContext xctxt,
398:                    int predPos, DTM dtm, int context, int pos) {
399:
400:                try {
401:                    DTMAxisTraverser traverser = dtm
402:                            .getAxisTraverser(Axis.PRECEDINGSIBLING);
403:
404:                    for (int child = traverser.first(context); DTM.NULL != child; child = traverser
405:                            .next(context, child)) {
406:                        try {
407:                            xctxt.pushCurrentNode(child);
408:
409:                            if (NodeTest.SCORE_NONE != super .execute(xctxt,
410:                                    child)) {
411:                                boolean pass = true;
412:
413:                                try {
414:                                    xctxt.pushSubContextList(this );
415:
416:                                    for (int i = 0; i < predPos; i++) {
417:                                        xctxt.pushPredicatePos(i);
418:                                        try {
419:                                            XObject pred = m_predicates[i]
420:                                                    .execute(xctxt);
421:
422:                                            try {
423:                                                if (XObject.CLASS_NUMBER == pred
424:                                                        .getType()) {
425:                                                    throw new Error(
426:                                                            "Why: Should never have been called");
427:                                                } else if (!pred
428:                                                        .boolWithSideEffects()) {
429:                                                    pass = false;
430:
431:                                                    break;
432:                                                }
433:                                            } finally {
434:                                                pred.detach();
435:                                            }
436:                                        } finally {
437:                                            xctxt.popPredicatePos();
438:                                        }
439:                                    }
440:                                } finally {
441:                                    xctxt.popSubContextList();
442:                                }
443:
444:                                if (pass)
445:                                    pos--;
446:
447:                                if (pos < 1)
448:                                    return false;
449:                            }
450:                        } finally {
451:                            xctxt.popCurrentNode();
452:                        }
453:                    }
454:                } catch (javax.xml.transform.TransformerException se) {
455:
456:                    // TODO: should keep throw sax exception...
457:                    throw new java.lang.RuntimeException(se.getMessage());
458:                }
459:
460:                return (pos == 1);
461:            }
462:
463:            /**
464:             * Get the proximity position index of the current node based on this
465:             * node test.
466:             *
467:             *
468:             * @param xctxt XPath runtime context.
469:             * @param predPos Which predicate we're evaluating of foo[1][2][3].
470:             * @param findLast If true, don't terminate when the context node is found.
471:             *
472:             * @return the proximity position index of the current node based on the
473:             *         node test.
474:             */
475:            private final int getProximityPosition(XPathContext xctxt,
476:                    int predPos, boolean findLast) {
477:
478:                int pos = 0;
479:                int context = xctxt.getCurrentNode();
480:                DTM dtm = xctxt.getDTM(context);
481:                int parent = dtm.getParent(context);
482:
483:                try {
484:                    DTMAxisTraverser traverser = dtm
485:                            .getAxisTraverser(Axis.CHILD);
486:
487:                    for (int child = traverser.first(parent); DTM.NULL != child; child = traverser
488:                            .next(parent, child)) {
489:                        try {
490:                            xctxt.pushCurrentNode(child);
491:
492:                            if (NodeTest.SCORE_NONE != super .execute(xctxt,
493:                                    child)) {
494:                                boolean pass = true;
495:
496:                                try {
497:                                    xctxt.pushSubContextList(this );
498:
499:                                    for (int i = 0; i < predPos; i++) {
500:                                        xctxt.pushPredicatePos(i);
501:                                        try {
502:                                            XObject pred = m_predicates[i]
503:                                                    .execute(xctxt);
504:
505:                                            try {
506:                                                if (XObject.CLASS_NUMBER == pred
507:                                                        .getType()) {
508:                                                    if ((pos + 1) != (int) pred
509:                                                            .numWithSideEffects()) {
510:                                                        pass = false;
511:
512:                                                        break;
513:                                                    }
514:                                                } else if (!pred
515:                                                        .boolWithSideEffects()) {
516:                                                    pass = false;
517:
518:                                                    break;
519:                                                }
520:                                            } finally {
521:                                                pred.detach();
522:                                            }
523:                                        } finally {
524:                                            xctxt.popPredicatePos();
525:                                        }
526:                                    }
527:                                } finally {
528:                                    xctxt.popSubContextList();
529:                                }
530:
531:                                if (pass)
532:                                    pos++;
533:
534:                                if (!findLast && child == context) {
535:                                    return pos;
536:                                }
537:                            }
538:                        } finally {
539:                            xctxt.popCurrentNode();
540:                        }
541:                    }
542:                } catch (javax.xml.transform.TransformerException se) {
543:
544:                    // TODO: should keep throw sax exception...
545:                    throw new java.lang.RuntimeException(se.getMessage());
546:                }
547:
548:                return pos;
549:            }
550:
551:            /**
552:             * Get the proximity position index of the current node based on this
553:             * node test.
554:             *
555:             *
556:             * @param xctxt XPath runtime context.
557:             *
558:             * @return the proximity position index of the current node based on the
559:             *         node test.
560:             */
561:            public int getProximityPosition(XPathContext xctxt) {
562:                return getProximityPosition(xctxt, xctxt.getPredicatePos(),
563:                        false);
564:            }
565:
566:            /**
567:             * Get the count of the nodes that match the test, which is the proximity
568:             * position of the last node that can pass this test in the sub context
569:             * selection.  In XSLT 1-based indexing, this count is the index of the last
570:             * node.
571:             *
572:             *
573:             * @param xctxt XPath runtime context.
574:             *
575:             * @return the count of the nodes that match the test.
576:             */
577:            public int getLastPos(XPathContext xctxt) {
578:                return getProximityPosition(xctxt, xctxt.getPredicatePos(),
579:                        true);
580:            }
581:
582:            /**
583:             * Execute the match pattern step relative to another step.
584:             *
585:             *
586:             * @param xctxt The XPath runtime context.
587:             * @param dtm The DTM of the current node.
588:             * @param currentNode The current node context.
589:             *
590:             * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
591:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
592:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
593:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
594:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
595:             *
596:             * @throws javax.xml.transform.TransformerException
597:             */
598:            protected final XObject executeRelativePathPattern(
599:                    XPathContext xctxt, DTM dtm, int currentNode)
600:                    throws javax.xml.transform.TransformerException {
601:
602:                XObject score = NodeTest.SCORE_NONE;
603:                int context = currentNode;
604:                DTMAxisTraverser traverser;
605:
606:                traverser = dtm.getAxisTraverser(m_axis);
607:
608:                for (int relative = traverser.first(context); DTM.NULL != relative; relative = traverser
609:                        .next(context, relative)) {
610:                    try {
611:                        xctxt.pushCurrentNode(relative);
612:
613:                        score = execute(xctxt);
614:
615:                        if (score != NodeTest.SCORE_NONE)
616:                            break;
617:                    } finally {
618:                        xctxt.popCurrentNode();
619:                    }
620:                }
621:
622:                return score;
623:            }
624:
625:            /**
626:             * Execute the predicates on this step to determine if the current node 
627:             * should be filtered or accepted.
628:             *
629:             * @param xctxt The XPath runtime context.
630:             * @param dtm The DTM of the current node.
631:             * @param currentNode The current node context.
632:             *
633:             * @return true if the node should be accepted, false otherwise.
634:             *
635:             * @throws javax.xml.transform.TransformerException
636:             */
637:            protected final boolean executePredicates(XPathContext xctxt,
638:                    DTM dtm, int currentNode)
639:                    throws javax.xml.transform.TransformerException {
640:
641:                boolean result = true;
642:                boolean positionAlreadySeen = false;
643:                int n = getPredicateCount();
644:
645:                try {
646:                    xctxt.pushSubContextList(this );
647:
648:                    for (int i = 0; i < n; i++) {
649:                        xctxt.pushPredicatePos(i);
650:
651:                        try {
652:                            XObject pred = m_predicates[i].execute(xctxt);
653:
654:                            try {
655:                                if (XObject.CLASS_NUMBER == pred.getType()) {
656:                                    int pos = (int) pred.num();
657:
658:                                    if (positionAlreadySeen) {
659:                                        result = (pos == 1);
660:
661:                                        break;
662:                                    } else {
663:                                        positionAlreadySeen = true;
664:
665:                                        if (!checkProximityPosition(xctxt, i,
666:                                                dtm, currentNode, pos)) {
667:                                            result = false;
668:
669:                                            break;
670:                                        }
671:                                    }
672:
673:                                } else if (!pred.boolWithSideEffects()) {
674:                                    result = false;
675:
676:                                    break;
677:                                }
678:                            } finally {
679:                                pred.detach();
680:                            }
681:                        } finally {
682:                            xctxt.popPredicatePos();
683:                        }
684:                    }
685:                } finally {
686:                    xctxt.popSubContextList();
687:                }
688:
689:                return result;
690:            }
691:
692:            /**
693:             * Get the string represenentation of this step for diagnostic purposes.
694:             *
695:             *
696:             * @return A string representation of this step, built by reverse-engineering 
697:             * the contained info.
698:             */
699:            public String toString() {
700:
701:                StringBuffer buf = new StringBuffer();
702:
703:                for (StepPattern pat = this ; pat != null; pat = pat.m_relativePathPattern) {
704:                    if (pat != this )
705:                        buf.append("/");
706:
707:                    buf.append(Axis.getNames(pat.m_axis));
708:                    buf.append("::");
709:
710:                    if (0x000005000 == pat.m_whatToShow) {
711:                        buf.append("doc()");
712:                    } else if (DTMFilter.SHOW_BYFUNCTION == pat.m_whatToShow) {
713:                        buf.append("function()");
714:                    } else if (DTMFilter.SHOW_ALL == pat.m_whatToShow) {
715:                        buf.append("node()");
716:                    } else if (DTMFilter.SHOW_TEXT == pat.m_whatToShow) {
717:                        buf.append("text()");
718:                    } else if (DTMFilter.SHOW_PROCESSING_INSTRUCTION == pat.m_whatToShow) {
719:                        buf.append("processing-instruction(");
720:
721:                        if (null != pat.m_name) {
722:                            buf.append(pat.m_name);
723:                        }
724:
725:                        buf.append(")");
726:                    } else if (DTMFilter.SHOW_COMMENT == pat.m_whatToShow) {
727:                        buf.append("comment()");
728:                    } else if (null != pat.m_name) {
729:                        if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow) {
730:                            buf.append("@");
731:                        }
732:
733:                        if (null != pat.m_namespace) {
734:                            buf.append("{");
735:                            buf.append(pat.m_namespace);
736:                            buf.append("}");
737:                        }
738:
739:                        buf.append(pat.m_name);
740:                    } else if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow) {
741:                        buf.append("@");
742:                    } else if ((DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT) == pat.m_whatToShow) {
743:                        buf.append("doc-root()");
744:                    } else {
745:                        buf.append("?" + Integer.toHexString(pat.m_whatToShow));
746:                    }
747:
748:                    if (null != pat.m_predicates) {
749:                        for (int i = 0; i < pat.m_predicates.length; i++) {
750:                            buf.append("[");
751:                            buf.append(pat.m_predicates[i]);
752:                            buf.append("]");
753:                        }
754:                    }
755:                }
756:
757:                return buf.toString();
758:            }
759:
760:            /** Set to true to send diagnostics about pattern matches to the consol. */
761:            private static final boolean DEBUG_MATCHES = false;
762:
763:            /**
764:             * Get the match score of the given node.
765:             *
766:             * @param xctxt The XPath runtime context.
767:             * @param context The node to be tested.
768:             *
769:             * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
770:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
771:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
772:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
773:             *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
774:             *
775:             * @throws javax.xml.transform.TransformerException
776:             */
777:            public double getMatchScore(XPathContext xctxt, int context)
778:                    throws javax.xml.transform.TransformerException {
779:
780:                xctxt.pushCurrentNode(context);
781:                xctxt.pushCurrentExpressionNode(context);
782:
783:                try {
784:                    XObject score = execute(xctxt);
785:
786:                    return score.num();
787:                } finally {
788:                    xctxt.popCurrentNode();
789:                    xctxt.popCurrentExpressionNode();
790:                }
791:
792:                // return XPath.MATCH_SCORE_NONE;
793:            }
794:
795:            /**
796:             * Set the axis that this step should follow. 
797:             *
798:             *
799:             * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
800:             */
801:            public void setAxis(int axis) {
802:                m_axis = axis;
803:            }
804:
805:            /**
806:             * Get the axis that this step follows. 
807:             *
808:             *
809:             * @return The Axis for this test, one of of Axes.ANCESTORORSELF, etc.
810:             */
811:            public int getAxis() {
812:                return m_axis;
813:            }
814:
815:            class PredOwner implements  ExpressionOwner {
816:                int m_index;
817:
818:                PredOwner(int index) {
819:                    m_index = index;
820:                }
821:
822:                /**
823:                 * @see ExpressionOwner#getExpression()
824:                 */
825:                public Expression getExpression() {
826:                    return m_predicates[m_index];
827:                }
828:
829:                /**
830:                 * @see ExpressionOwner#setExpression(Expression)
831:                 */
832:                public void setExpression(Expression exp) {
833:                    exp.exprSetParent(StepPattern.this );
834:                    m_predicates[m_index] = exp;
835:                }
836:            }
837:
838:            /**
839:             * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
840:             */
841:            public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) {
842:                if (visitor.visitMatchPattern(owner, this )) {
843:                    callSubtreeVisitors(visitor);
844:                }
845:            }
846:
847:            /**
848:             * Call the visitors on the subtree.  Factored out from callVisitors 
849:             * so it may be called by derived classes.
850:             */
851:            protected void callSubtreeVisitors(XPathVisitor visitor) {
852:                if (null != m_predicates) {
853:                    int n = m_predicates.length;
854:                    for (int i = 0; i < n; i++) {
855:                        ExpressionOwner predOwner = new PredOwner(i);
856:                        if (visitor.visitPredicate(predOwner, m_predicates[i])) {
857:                            m_predicates[i].callVisitors(predOwner, visitor);
858:                        }
859:                    }
860:                }
861:                if (null != m_relativePathPattern) {
862:                    m_relativePathPattern.callVisitors(this , visitor);
863:                }
864:            }
865:
866:            /**
867:             * @see ExpressionOwner#getExpression()
868:             */
869:            public Expression getExpression() {
870:                return m_relativePathPattern;
871:            }
872:
873:            /**
874:             * @see ExpressionOwner#setExpression(Expression)
875:             */
876:            public void setExpression(Expression exp) {
877:                exp.exprSetParent(this );
878:                m_relativePathPattern = (StepPattern) exp;
879:            }
880:
881:            /**
882:             * @see Expression#deepEquals(Expression)
883:             */
884:            public boolean deepEquals(Expression expr) {
885:                if (!super .deepEquals(expr))
886:                    return false;
887:
888:                StepPattern sp = (StepPattern) expr;
889:
890:                if (null != m_predicates) {
891:                    int n = m_predicates.length;
892:                    if ((null == sp.m_predicates)
893:                            || (sp.m_predicates.length != n))
894:                        return false;
895:                    for (int i = 0; i < n; i++) {
896:                        if (!m_predicates[i].deepEquals(sp.m_predicates[i]))
897:                            return false;
898:                    }
899:                } else if (null != sp.m_predicates)
900:                    return false;
901:
902:                if (null != m_relativePathPattern) {
903:                    if (!m_relativePathPattern
904:                            .deepEquals(sp.m_relativePathPattern))
905:                        return false;
906:                } else if (sp.m_relativePathPattern != null)
907:                    return false;
908:
909:                return true;
910:            }
911:
912:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.