001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: ContextMatchStepPattern.java 468655 2006-10-28 07:12:06Z minchau $
020 */
021 package org.apache.xpath.patterns;
022
023 import org.apache.xml.dtm.Axis;
024 import org.apache.xml.dtm.DTM;
025 import org.apache.xml.dtm.DTMAxisTraverser;
026 import org.apache.xml.dtm.DTMFilter;
027 import org.apache.xpath.XPathContext;
028 import org.apache.xpath.axes.WalkerFactory;
029 import org.apache.xpath.objects.XObject;
030 /**
031 * Special context node pattern matcher.
032 */
033 public class ContextMatchStepPattern extends StepPattern
034 {
035 static final long serialVersionUID = -1888092779313211942L;
036
037 /**
038 * Construct a ContextMatchStepPattern.
039 *
040 */
041 public ContextMatchStepPattern(int axis, int paxis)
042 {
043 super(DTMFilter.SHOW_ALL, axis, paxis);
044 }
045
046 /**
047 * Execute this pattern step, including predicates.
048 *
049 *
050 * @param xctxt XPath runtime context.
051 *
052 * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
053 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
054 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
055 * {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
056 * {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
057 *
058 * @throws javax.xml.transform.TransformerException
059 */
060 public XObject execute(XPathContext xctxt)
061 throws javax.xml.transform.TransformerException
062 {
063
064 if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
065 return getStaticScore();
066 else
067 return this.SCORE_NONE;
068 }
069
070 /**
071 * Execute the match pattern step relative to another step.
072 *
073 *
074 * @param xctxt The XPath runtime context.
075 * NEEDSDOC @param prevStep
076 *
077 * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
078 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
079 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
080 * {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
081 * {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
082 *
083 * @throws javax.xml.transform.TransformerException
084 */
085 public XObject executeRelativePathPattern(
086 XPathContext xctxt, StepPattern prevStep)
087 throws javax.xml.transform.TransformerException
088 {
089
090 XObject score = NodeTest.SCORE_NONE;
091 int context = xctxt.getCurrentNode();
092 DTM dtm = xctxt.getDTM(context);
093
094 if (null != dtm)
095 {
096 int predContext = xctxt.getCurrentNode();
097 DTMAxisTraverser traverser;
098
099 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 }