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