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: KeyManager.java 468645 2006-10-28 06:57:24Z minchau $
020     */
021    package org.apache.xalan.transformer;
022    
023    import java.util.Vector;
024    
025    import org.apache.xalan.templates.ElemTemplateElement;
026    import org.apache.xml.utils.PrefixResolver;
027    import org.apache.xml.utils.QName;
028    import org.apache.xml.utils.XMLString;
029    import org.apache.xpath.XPathContext;
030    import org.apache.xpath.objects.XNodeSet;
031    
032    /**
033     * This class manages the key tables.
034     */
035    public class KeyManager
036    {
037    
038      /**
039       * Table of tables of element keys.
040       * @see org.apache.xalan.transformer.KeyTable
041       */
042      private transient Vector m_key_tables = null;
043    
044      /**
045       * Given a valid element key, return the corresponding node list.
046       *
047       * @param xctxt The XPath runtime state
048       * @param doc The document node
049       * @param name The key element name
050       * @param ref The key value we're looking for 
051       * @param nscontext The prefix resolver for the execution context
052       *
053       * @return A nodelist of nodes mathing the given key
054       *
055       * @throws javax.xml.transform.TransformerException
056       */
057      public XNodeSet getNodeSetDTMByKey(
058              XPathContext xctxt, int doc, QName name, XMLString ref, PrefixResolver nscontext)
059                throws javax.xml.transform.TransformerException
060      {
061    
062        XNodeSet nl = null;
063        ElemTemplateElement template = (ElemTemplateElement) nscontext;  // yuck -sb
064    
065        if ((null != template)
066                && null != template.getStylesheetRoot().getKeysComposed())
067        {
068          boolean foundDoc = false;
069    
070          if (null == m_key_tables)
071          {
072            m_key_tables = new Vector(4);
073          }
074          else
075          {
076            int nKeyTables = m_key_tables.size();
077    
078            for (int i = 0; i < nKeyTables; i++)
079            {
080              KeyTable kt = (KeyTable) m_key_tables.elementAt(i);
081    
082              if (kt.getKeyTableName().equals(name) && doc == kt.getDocKey())
083              {
084                nl = kt.getNodeSetDTMByKey(name, ref);
085    
086                if (nl != null)
087                {
088                  foundDoc = true;
089    
090                  break;
091                }
092              }
093            }
094          }
095    
096          if ((null == nl) &&!foundDoc /* && m_needToBuildKeysTable */)
097          {
098            KeyTable kt =
099              new KeyTable(doc, nscontext, name,
100                           template.getStylesheetRoot().getKeysComposed(),
101                           xctxt);
102    
103            m_key_tables.addElement(kt);
104    
105            if (doc == kt.getDocKey())
106            {
107              foundDoc = true;
108              nl = kt.getNodeSetDTMByKey(name, ref);
109            }
110          }
111        }
112    
113        return nl;
114      }
115    }