14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file
44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information
54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file
64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License.
84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at
94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software
134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and
164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License.
174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: FunctionPattern.java 468655 2006-10-28 07:12:06Z minchau $
204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath.patterns;
224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM;
244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMIterator;
254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.Expression;
264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.ExpressionOwner;
274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext;
284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathVisitor;
294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XNumber;
304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject;
314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/**
334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Match pattern step that contains a function.
344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage advanced
354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class FunctionPattern extends StepPattern
374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{
384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    static final long serialVersionUID = -5426793413091209944L;
394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Construct a FunctionPattern from a
424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * {@link org.apache.xpath.functions.Function expression}.
434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * NEEDSDOC @param expr
454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public FunctionPattern(Expression expr, int axis, int predaxis)
474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    super(0, null, null, axis, predaxis);
504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_functionExpr = expr;
524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Static calc of match score.
564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public final void calcScore()
584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_score = SCORE_OTHER;
614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null == m_targetString)
634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      calcTargetString();
644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Should be a {@link org.apache.xpath.functions.Function expression}.
684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *  @serial
694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  Expression m_functionExpr;
714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * This function is used to fixup variables from QNames to stack frame
744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * indexes at stylesheet build time.
754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param vars List of QNames that correspond to variables.  This list
764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * should be searched backwards for the first qualified name that
774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * corresponds to the variable reference qname.  The position of the
784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * QName in the vector from the start of the vector will be its position
794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * in the stack frame (but variables above the globalsTop value will need
804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * to be offset to the current stack frame).
814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public void fixupVariables(java.util.Vector vars, int globalsSize)
834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    super.fixupVariables(vars, globalsSize);
854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_functionExpr.fixupVariables(vars, globalsSize);
864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Test a node to see if it matches the given node test.
914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param xctxt XPath runtime context.
934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws javax.xml.transform.TransformerException
1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public XObject execute(XPathContext xctxt, int context)
1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws javax.xml.transform.TransformerException
1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    XNumber score = SCORE_NONE;
1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null != nl)
1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      int n;
1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      while (DTM.NULL != (n = nl.nextNode()))
1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        if (score == SCORE_OTHER)
1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          context = n;
1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          break;
1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // nl.detach();
1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    nl.detach();
1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return score;
1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Test a node to see if it matches the given node test.
1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param xctxt XPath runtime context.
1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws javax.xml.transform.TransformerException
1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public XObject execute(XPathContext xctxt, int context,
1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                         DTM dtm, int expType)
1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws javax.xml.transform.TransformerException
1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    XNumber score = SCORE_NONE;
1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null != nl)
1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      int n;
1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      while (DTM.NULL != (n = nl.nextNode()))
1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        if (score == SCORE_OTHER)
1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          context = n;
1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          break;
1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      nl.detach();
1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return score;
1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Test a node to see if it matches the given node test.
1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param xctxt XPath runtime context.
1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws javax.xml.transform.TransformerException
1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public XObject execute(XPathContext xctxt)
1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws javax.xml.transform.TransformerException
1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    int context = xctxt.getCurrentNode();
1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    XNumber score = SCORE_NONE;
1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null != nl)
1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      int n;
1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      while (DTM.NULL != (n = nl.nextNode()))
2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        score = (n == context) ? SCORE_OTHER : SCORE_NONE;
2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        if (score == SCORE_OTHER)
2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          context = n;
2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          break;
2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      nl.detach();
2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return score;
2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  class FunctionOwner implements ExpressionOwner
2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    /**
2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson     * @see ExpressionOwner#getExpression()
2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson     */
2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    public Expression getExpression()
2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return m_functionExpr;
2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    /**
2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson     * @see ExpressionOwner#setExpression(Expression)
2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson     */
2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    public void setExpression(Expression exp)
2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    	exp.exprSetParent(FunctionPattern.this);
2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    	m_functionExpr = exp;
2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Call the visitor for the function.
2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  protected void callSubtreeVisitors(XPathVisitor visitor)
2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_functionExpr.callVisitors(new FunctionOwner(), visitor);
2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    super.callSubtreeVisitors(visitor);
2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson}
249