1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: ContextMatchStepPattern.java 468655 2006-10-28 07:12:06Z minchau $
20  */
21 package org.apache.xpath.patterns;
22 
23 import org.apache.xml.dtm.Axis;
24 import org.apache.xml.dtm.DTM;
25 import org.apache.xml.dtm.DTMAxisTraverser;
26 import org.apache.xml.dtm.DTMFilter;
27 import org.apache.xpath.XPathContext;
28 import org.apache.xpath.axes.WalkerFactory;
29 import org.apache.xpath.objects.XObject;
30 /**
31  * Special context node pattern matcher.
32  */
33 public class ContextMatchStepPattern extends StepPattern
34 {
35     static final long serialVersionUID = -1888092779313211942L;
36 
37   /**
38    * Construct a ContextMatchStepPattern.
39    *
40    */
ContextMatchStepPattern(int axis, int paxis)41   public ContextMatchStepPattern(int axis, int paxis)
42   {
43     super(DTMFilter.SHOW_ALL, axis, paxis);
44   }
45 
46   /**
47    * Execute this pattern step, including predicates.
48    *
49    *
50    * @param xctxt XPath runtime context.
51    *
52    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
53    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
54    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
55    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
56    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
57    *
58    * @throws javax.xml.transform.TransformerException
59    */
execute(XPathContext xctxt)60   public XObject execute(XPathContext xctxt)
61           throws javax.xml.transform.TransformerException
62   {
63 
64     if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
65       return getStaticScore();
66     else
67       return this.SCORE_NONE;
68   }
69 
70   /**
71    * Execute the match pattern step relative to another step.
72    *
73    *
74    * @param xctxt The XPath runtime context.
75    * NEEDSDOC @param prevStep
76    *
77    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
78    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
79    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
80    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
81    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
82    *
83    * @throws javax.xml.transform.TransformerException
84    */
executeRelativePathPattern( XPathContext xctxt, StepPattern prevStep)85   public XObject executeRelativePathPattern(
86           XPathContext xctxt, StepPattern prevStep)
87             throws javax.xml.transform.TransformerException
88   {
89 
90     XObject score = NodeTest.SCORE_NONE;
91     int context = xctxt.getCurrentNode();
92     DTM dtm = xctxt.getDTM(context);
93 
94     if (null != dtm)
95     {
96       int predContext = xctxt.getCurrentNode();
97       DTMAxisTraverser traverser;
98 
99       int axis = m_axis;
100 
101       boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis);
102       boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot())
103                                  == DTM.ATTRIBUTE_NODE);
104 
105       if((Axis.PRECEDING == axis) && iterRootIsAttr)
106       {
107         axis = Axis.PRECEDINGANDANCESTOR;
108       }
109 
110       traverser = dtm.getAxisTraverser(axis);
111 
112       for (int relative = traverser.first(context); DTM.NULL != relative;
113               relative = traverser.next(context, relative))
114       {
115         try
116         {
117           xctxt.pushCurrentNode(relative);
118 
119           score = execute(xctxt);
120 
121           if (score != NodeTest.SCORE_NONE)
122           {
123 	      //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
124 	      //       predContext, relative);
125 	      if (executePredicates(xctxt, dtm, context))
126 		  return score;
127 
128 	      score = NodeTest.SCORE_NONE;
129           }
130 
131           if(needToTraverseAttrs && iterRootIsAttr
132              && (DTM.ELEMENT_NODE == dtm.getNodeType(relative)))
133           {
134             int xaxis = Axis.ATTRIBUTE;
135             for (int i = 0; i < 2; i++)
136             {
137               DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis);
138 
139               for (int arelative = atraverser.first(relative);
140                       DTM.NULL != arelative;
141                       arelative = atraverser.next(relative, arelative))
142               {
143                 try
144                 {
145                   xctxt.pushCurrentNode(arelative);
146 
147                   score = execute(xctxt);
148 
149                   if (score != NodeTest.SCORE_NONE)
150                   {
151 		      //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
152 		      //       predContext, arelative);
153 
154                     if (score != NodeTest.SCORE_NONE)
155                       return score;
156                   }
157                 }
158                 finally
159                 {
160                   xctxt.popCurrentNode();
161                 }
162               }
163               xaxis = Axis.NAMESPACE;
164             }
165           }
166 
167         }
168         finally
169         {
170           xctxt.popCurrentNode();
171         }
172       }
173 
174     }
175 
176     return score;
177   }
178 
179 }
180