• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: FunctionPattern.java 468655 2006-10-28 07:12:06Z minchau $
20  */
21 package org.apache.xpath.patterns;
22 
23 import org.apache.xml.dtm.DTM;
24 import org.apache.xml.dtm.DTMIterator;
25 import org.apache.xpath.Expression;
26 import org.apache.xpath.ExpressionOwner;
27 import org.apache.xpath.XPathContext;
28 import org.apache.xpath.XPathVisitor;
29 import org.apache.xpath.objects.XNumber;
30 import org.apache.xpath.objects.XObject;
31 
32 /**
33  * Match pattern step that contains a function.
34  * @xsl.usage advanced
35  */
36 public class FunctionPattern extends StepPattern
37 {
38     static final long serialVersionUID = -5426793413091209944L;
39 
40   /**
41    * Construct a FunctionPattern from a
42    * {@link org.apache.xpath.functions.Function expression}.
43    *
44    * NEEDSDOC @param expr
45    */
FunctionPattern(Expression expr, int axis, int predaxis)46   public FunctionPattern(Expression expr, int axis, int predaxis)
47   {
48 
49     super(0, null, null, axis, predaxis);
50 
51     m_functionExpr = expr;
52   }
53 
54   /**
55    * Static calc of match score.
56    */
calcScore()57   public final void calcScore()
58   {
59 
60     m_score = SCORE_OTHER;
61 
62     if (null == m_targetString)
63       calcTargetString();
64   }
65 
66   /**
67    * Should be a {@link org.apache.xpath.functions.Function expression}.
68    *  @serial
69    */
70   Expression m_functionExpr;
71 
72   /**
73    * This function is used to fixup variables from QNames to stack frame
74    * indexes at stylesheet build time.
75    * @param vars List of QNames that correspond to variables.  This list
76    * should be searched backwards for the first qualified name that
77    * corresponds to the variable reference qname.  The position of the
78    * QName in the vector from the start of the vector will be its position
79    * in the stack frame (but variables above the globalsTop value will need
80    * to be offset to the current stack frame).
81    */
fixupVariables(java.util.Vector vars, int globalsSize)82   public void fixupVariables(java.util.Vector vars, int globalsSize)
83   {
84     super.fixupVariables(vars, globalsSize);
85     m_functionExpr.fixupVariables(vars, globalsSize);
86   }
87 
88 
89   /**
90    * Test a node to see if it matches the given node test.
91    *
92    * @param xctxt XPath runtime context.
93    *
94    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
95    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
96    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
97    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
98    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
99    *
100    * @throws javax.xml.transform.TransformerException
101    */
execute(XPathContext xctxt, int context)102   public XObject execute(XPathContext xctxt, int context)
103           throws javax.xml.transform.TransformerException
104   {
105 
106     DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
107     XNumber score = SCORE_NONE;
108 
109     if (null != nl)
110     {
111       int n;
112 
113       while (DTM.NULL != (n = nl.nextNode()))
114       {
115         score = (n == context) ? SCORE_OTHER : SCORE_NONE;
116 
117         if (score == SCORE_OTHER)
118         {
119           context = n;
120 
121           break;
122         }
123       }
124 
125       // nl.detach();
126     }
127     nl.detach();
128 
129     return score;
130   }
131 
132   /**
133    * Test a node to see if it matches the given node test.
134    *
135    * @param xctxt XPath runtime context.
136    *
137    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
138    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
139    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
140    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
141    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
142    *
143    * @throws javax.xml.transform.TransformerException
144    */
execute(XPathContext xctxt, int context, DTM dtm, int expType)145   public XObject execute(XPathContext xctxt, int context,
146                          DTM dtm, int expType)
147           throws javax.xml.transform.TransformerException
148   {
149 
150     DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
151     XNumber score = SCORE_NONE;
152 
153     if (null != nl)
154     {
155       int n;
156 
157       while (DTM.NULL != (n = nl.nextNode()))
158       {
159         score = (n == context) ? SCORE_OTHER : SCORE_NONE;
160 
161         if (score == SCORE_OTHER)
162         {
163           context = n;
164 
165           break;
166         }
167       }
168 
169       nl.detach();
170     }
171 
172     return score;
173   }
174 
175   /**
176    * Test a node to see if it matches the given node test.
177    *
178    * @param xctxt XPath runtime context.
179    *
180    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
181    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
182    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
183    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
184    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
185    *
186    * @throws javax.xml.transform.TransformerException
187    */
execute(XPathContext xctxt)188   public XObject execute(XPathContext xctxt)
189           throws javax.xml.transform.TransformerException
190   {
191 
192     int context = xctxt.getCurrentNode();
193     DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
194     XNumber score = SCORE_NONE;
195 
196     if (null != nl)
197     {
198       int n;
199 
200       while (DTM.NULL != (n = nl.nextNode()))
201       {
202         score = (n == context) ? SCORE_OTHER : SCORE_NONE;
203 
204         if (score == SCORE_OTHER)
205         {
206           context = n;
207 
208           break;
209         }
210       }
211 
212       nl.detach();
213     }
214 
215     return score;
216   }
217 
218   class FunctionOwner implements ExpressionOwner
219   {
220     /**
221      * @see ExpressionOwner#getExpression()
222      */
getExpression()223     public Expression getExpression()
224     {
225       return m_functionExpr;
226     }
227 
228 
229     /**
230      * @see ExpressionOwner#setExpression(Expression)
231      */
setExpression(Expression exp)232     public void setExpression(Expression exp)
233     {
234     	exp.exprSetParent(FunctionPattern.this);
235     	m_functionExpr = exp;
236     }
237   }
238 
239   /**
240    * Call the visitor for the function.
241    */
callSubtreeVisitors(XPathVisitor visitor)242   protected void callSubtreeVisitors(XPathVisitor visitor)
243   {
244     m_functionExpr.callVisitors(new FunctionOwner(), visitor);
245     super.callSubtreeVisitors(visitor);
246   }
247 
248 }
249