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: AVTPartXPath.java 468643 2006-10-28 06:56:03Z minchau $
020     */
021    package org.apache.xalan.templates;
022    
023    import org.apache.xml.utils.FastStringBuffer;
024    import org.apache.xpath.XPath;
025    import org.apache.xpath.XPathContext;
026    import org.apache.xpath.XPathFactory;
027    import org.apache.xpath.compiler.XPathParser;
028    import org.apache.xpath.objects.XObject;
029    
030    /**
031     * Simple string part of a complex AVT.
032     * @xsl.usage internal
033     */
034    public class AVTPartXPath extends AVTPart
035    {
036        static final long serialVersionUID = -4460373807550527675L;
037    
038      /**
039       * The XPath object contained in this part.
040       * @serial
041       */
042      private XPath m_xpath;
043      
044      /**
045       * This function is used to fixup variables from QNames to stack frame 
046       * indexes at stylesheet build time.
047       * @param vars List of QNames that correspond to variables.  This list 
048       * should be searched backwards for the first qualified name that 
049       * corresponds to the variable reference qname.  The position of the 
050       * QName in the vector from the start of the vector will be its position 
051       * in the stack frame (but variables above the globalsTop value will need 
052       * to be offset to the current stack frame).
053       */
054      public void fixupVariables(java.util.Vector vars, int globalsSize)
055      {
056        m_xpath.fixupVariables(vars, globalsSize);
057      }
058      
059      /**
060       * Tell if this expression or it's subexpressions can traverse outside 
061       * the current subtree.
062       * 
063       * @return true if traversal outside the context node's subtree can occur.
064       */
065       public boolean canTraverseOutsideSubtree()
066       {
067        return m_xpath.getExpression().canTraverseOutsideSubtree();
068       }
069    
070      /**
071       * Construct a simple AVT part.
072       *
073       * @param xpath Xpath section of AVT 
074       */
075      public AVTPartXPath(XPath xpath)
076      {
077        m_xpath = xpath;
078      }
079    
080      /**
081       * Construct a simple AVT part.
082       * 
083       * @param val A pure string section of an AVT.
084       * @param nsNode An object which can be used to determine the
085       * Namespace Name (URI) for any Namespace prefix used in the XPath. 
086       * Usually this is based on the context where the XPath was specified,
087       * such as a node within a Stylesheet.
088       * @param xpathProcessor XPath parser
089       * @param factory XPath factory
090       * @param liaison An XPathContext object, providing infomation specific
091       * to this invocation and this thread. Maintains SAX output state, 
092       * variables, error handler and so on, so the transformation/XPath 
093       * object itself can be simultaneously invoked from multiple threads.
094       *
095       * @throws javax.xml.transform.TransformerException
096       * TODO: Fix or remove this unused c'tor.
097       */
098      public AVTPartXPath(
099              String val, org.apache.xml.utils.PrefixResolver nsNode, 
100              XPathParser xpathProcessor, XPathFactory factory, 
101              XPathContext liaison)
102                throws javax.xml.transform.TransformerException
103      {
104        m_xpath = new XPath(val, null, nsNode, XPath.SELECT, liaison.getErrorListener());
105      }
106    
107      /**
108       * Get the AVT part as the original string.
109       *
110       * @return the AVT part as the original string.
111       */
112      public String getSimpleString()
113      {
114        return "{" + m_xpath.getPatternString() + "}";
115      }
116    
117      /**
118       * Write the value into the buffer.
119       *
120       * @param xctxt An XPathContext object, providing infomation specific
121       * to this invocation and this thread. Maintains SAX state, variables, 
122       * error handler and  so on, so the transformation/XPath object itself
123       * can be simultaneously invoked from multiple threads.
124       * @param buf Buffer to write into.
125       * @param context The current source tree context.
126       * @param nsNode The current namespace context (stylesheet tree context).
127       *
128       * @throws javax.xml.transform.TransformerException
129       */
130      public void evaluate(
131              XPathContext xctxt, FastStringBuffer buf, int context, org.apache.xml.utils.PrefixResolver nsNode)
132                throws javax.xml.transform.TransformerException
133      {
134    
135        XObject xobj = m_xpath.execute(xctxt, context, nsNode);
136    
137        if (null != xobj)
138        {
139          xobj.appendToFsb(buf);
140        }
141      }
142      
143      /**
144       * @see XSLTVisitable#callVisitors(XSLTVisitor)
145       */
146      public void callVisitors(XSLTVisitor visitor)
147      {
148            m_xpath.getExpression().callVisitors(m_xpath, visitor);
149      }
150    }