KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > transformer > KeyRefIterator


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: KeyRefIterator.java,v 1.17 2004/02/16 20:41:29 minchau Exp $
18  */

19 package org.apache.xalan.transformer;
20
21 import java.util.Vector JavaDoc;
22
23 import org.apache.xalan.res.XSLMessages;
24 import org.apache.xalan.res.XSLTErrorResources;
25 import org.apache.xalan.templates.KeyDeclaration;
26 import org.apache.xml.dtm.DTM;
27 import org.apache.xml.dtm.DTMIterator;
28 import org.apache.xml.utils.QName;
29 import org.apache.xml.utils.XMLString;
30 import org.apache.xpath.objects.XNodeSet;
31 import org.apache.xpath.objects.XObject;
32
33 /**
34  * This class filters nodes from a key iterator, according to
35  * whether or not the use value matches the ref value.
36  * @xsl.usage internal
37  */

38 public class KeyRefIterator extends org.apache.xpath.axes.ChildTestIterator
39 {
40   /**
41    * Constructor KeyRefIterator
42    *
43    *
44    * @param ref Key value to match
45    * @param ki The main key iterator used to walk the source tree
46    */

47   public KeyRefIterator(QName name, XMLString ref, Vector JavaDoc keyDecls, DTMIterator ki)
48   {
49     super(null);
50     m_name = name;
51     m_ref = ref;
52     m_keyDeclarations = keyDecls;
53     m_keysNodes = ki;
54     setWhatToShow(org.apache.xml.dtm.DTMFilter.SHOW_ALL);
55   }
56   
57   DTMIterator m_keysNodes;
58   
59   /**
60    * Get the next node via getNextXXX. Bottlenecked for derived class override.
61    * @return The next node on the axis, or DTM.NULL.
62    */

63   protected int getNextNode()
64   {
65     int next;
66     while(DTM.NULL != (next = m_keysNodes.nextNode()))
67     {
68         if(DTMIterator.FILTER_ACCEPT == filterNode(next))
69             break;
70     }
71     m_lastFetched = next;
72     
73     return next;
74   }
75
76
77   /**
78    * Test whether a specified node is visible in the logical view of a
79    * TreeWalker or NodeIterator. This function will be called by the
80    * implementation of TreeWalker and NodeIterator; it is not intended to
81    * be called directly from user code.
82    *
83    * @param testnode The node to check to see if it passes the filter or not.
84    *
85    * @return a constant to determine whether the node is accepted,
86    * rejected, or skipped, as defined above .
87    */

88   public short filterNode(int testNode)
89   {
90     boolean foundKey = false;
91     Vector JavaDoc keys = m_keyDeclarations;
92
93     QName name = m_name;
94     KeyIterator ki = (KeyIterator)(((XNodeSet)m_keysNodes).getContainedIter());
95     org.apache.xpath.XPathContext xctxt = ki.getXPathContext();
96     
97     if(null == xctxt)
98         assertion(false, "xctxt can not be null here!");
99
100     try
101     {
102       XMLString lookupKey = m_ref;
103
104       // System.out.println("lookupKey: "+lookupKey);
105
int nDeclarations = keys.size();
106
107       // Walk through each of the declarations made with xsl:key
108
for (int i = 0; i < nDeclarations; i++)
109       {
110         KeyDeclaration kd = (KeyDeclaration) keys.elementAt(i);
111
112         // Only continue if the name on this key declaration
113
// matches the name on the iterator for this walker.
114
if (!kd.getName().equals(name))
115           continue;
116
117         foundKey = true;
118         // xctxt.setNamespaceContext(ki.getPrefixResolver());
119

120         // Query from the node, according the the select pattern in the
121
// use attribute in xsl:key.
122
XObject xuse = kd.getUse().execute(xctxt, testNode, ki.getPrefixResolver());
123
124         if (xuse.getType() != xuse.CLASS_NODESET)
125         {
126           XMLString exprResult = xuse.xstr();
127
128           if (lookupKey.equals(exprResult))
129             return DTMIterator.FILTER_ACCEPT;
130         }
131         else
132         {
133           DTMIterator nl = ((XNodeSet)xuse).iterRaw();
134           int useNode;
135           
136           while (DTM.NULL != (useNode = nl.nextNode()))
137           {
138             DTM dtm = getDTM(useNode);
139             XMLString exprResult = dtm.getStringValue(useNode);
140             if ((null != exprResult) && lookupKey.equals(exprResult))
141               return DTMIterator.FILTER_ACCEPT;
142           }
143         }
144
145       } // end for(int i = 0; i < nDeclarations; i++)
146
}
147     catch (javax.xml.transform.TransformerException JavaDoc te)
148     {
149       throw new org.apache.xml.utils.WrappedRuntimeException(te);
150     }
151
152     if (!foundKey)
153       throw new RuntimeException JavaDoc(
154         XSLMessages.createMessage(
155           XSLTErrorResources.ER_NO_XSLKEY_DECLARATION,
156           new Object JavaDoc[] { name.getLocalName()}));
157     return DTMIterator.FILTER_REJECT;
158   }
159
160   protected XMLString m_ref;
161   protected QName m_name;
162
163   /** Vector of Key declarations in the stylesheet.
164    * @serial */

165   protected Vector JavaDoc m_keyDeclarations;
166
167 }
168
Popular Tags