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