KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xalan > internal > xsltc > dom > KeyIndex


1 /*
2  * Copyright 2001-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: KeyIndex.java,v 1.13 2004/02/16 22:54:59 minchau Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.dom;
21
22 import java.util.StringTokenizer JavaDoc;
23
24 import com.sun.org.apache.xalan.internal.xsltc.DOM;
25 import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
26 import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
27 import com.sun.org.apache.xalan.internal.xsltc.util.IntegerArray;
28 import com.sun.org.apache.xml.internal.dtm.DTM;
29 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
30 import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;
31
32 /**
33  * @author Morten Jorgensen
34  * @author Santiago Pericas-Geertsen
35  */

36 public class KeyIndex extends DTMAxisIteratorBase {
37
38     /**
39      * A mapping between values and nodesets.
40      */

41     private Hashtable _index = new Hashtable();
42
43     /**
44      * The node set associated to the current value passed
45      * to lookupKey();
46      */

47     private IntegerArray _nodes = null;
48
49     /**
50      * The XSLTC DOM object if this KeyIndex is being used to implement the
51      * id() function.
52      */

53     private DOM _dom;
54     
55     private DOMEnhancedForDTM _enhancedDOM;
56
57     /**
58      * Store position after call to setMark()
59      */

60     private int _markedPosition = 0;
61
62     public KeyIndex(int dummy) {
63     }
64
65     public void setRestartable(boolean flag) {
66     }
67
68     /**
69      * Adds a node to the node list for a given value. Nodes will
70      * always be added in document order.
71      */

72     public void add(Object JavaDoc value, int node) {
73     IntegerArray nodes;
74     if ((nodes = (IntegerArray) _index.get(value)) == null) {
75         _index.put(value, nodes = new IntegerArray());
76     }
77     nodes.add(node);
78     }
79
80     /**
81      * Merge the current value's nodeset set by lookupKey() with _nodes.
82      */

83     public void merge(KeyIndex other) {
84     if (other == null) return;
85
86     if (other._nodes != null) {
87         if (_nodes == null) {
88         _nodes = other._nodes;
89         }
90         else {
91         _nodes.merge(other._nodes);
92         }
93     }
94     }
95
96     /**
97      * This method must be called by the code generated by the id() function
98      * prior to returning the node iterator. The lookup code for key() and
99      * id() differ in the way the lookup value can be whitespace separated
100      * list of tokens for the id() function, but a single string for the
101      * key() function.
102      */

103     public void lookupId(Object JavaDoc value) {
104     // Clear _nodes array
105
_nodes = null;
106
107     final StringTokenizer JavaDoc values = new StringTokenizer JavaDoc((String JavaDoc) value);
108     while (values.hasMoreElements()) {
109             final String JavaDoc token = (String JavaDoc) values.nextElement();
110         IntegerArray nodes = (IntegerArray) _index.get(token);
111
112             if (nodes == null && _enhancedDOM != null
113                 && _enhancedDOM.hasDOMSource()) {
114                 nodes = getDOMNodeById(token);
115             }
116
117         if (nodes == null) continue;
118
119         if (_nodes == null) {
120         _nodes = nodes;
121         }
122         else {
123         _nodes.merge(nodes);
124         }
125     }
126     }
127
128     /**
129      * Return an IntegerArray for the DOM Node which has the given id.
130      *
131      * @param id The id
132      * @return A IntegerArray representing the Node whose id is the given value.
133      */

134     public IntegerArray getDOMNodeById(String JavaDoc id) {
135         IntegerArray nodes = null;
136         if (_enhancedDOM != null) {
137             int ident = _enhancedDOM.getElementById(id);
138             if (ident != DTM.NULL) {
139             nodes = new IntegerArray();
140             _index.put(id, nodes);
141         nodes.add(ident);
142             }
143         }
144         return nodes;
145     }
146     
147     /**
148      * This method must be called by the code generated by the key() function
149      * prior to returning the node iterator.
150      */

151     public void lookupKey(Object JavaDoc value) {
152     _nodes = (IntegerArray) _index.get(value);
153     _position = 0;
154     }
155
156     /**
157      * Callers should not call next() after it returns END.
158      */

159     public int next() {
160     if (_nodes == null) return DTMAxisIterator.END;
161
162     return (_position < _nodes.cardinality()) ?
163         _dom.getNodeHandle(_nodes.at(_position++)) : DTMAxisIterator.END;
164     }
165
166     public int containsID(int node, Object JavaDoc value) {
167     final String JavaDoc string = (String JavaDoc)value;
168     if (string.indexOf(' ') > -1) {
169         final StringTokenizer JavaDoc values = new StringTokenizer JavaDoc(string);
170
171         while (values.hasMoreElements()) {
172                 final String JavaDoc token = (String JavaDoc) values.nextElement();
173         IntegerArray nodes = (IntegerArray) _index.get(token);
174
175         if (nodes == null && _enhancedDOM != null
176                     && _enhancedDOM.hasDOMSource()) {
177             nodes = getDOMNodeById(token);
178         }
179         if (nodes != null && nodes.indexOf(node) >= 0) {
180             return 1;
181         }
182         }
183         return 0;
184     }
185     else {
186         IntegerArray nodes = (IntegerArray) _index.get(value);
187             if (nodes == null && _enhancedDOM != null && _enhancedDOM.hasDOMSource()) {
188                 nodes = getDOMNodeById(string);
189             }
190         return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
191     }
192     }
193
194     public int containsKey(int node, Object JavaDoc value) {
195     final IntegerArray nodes = (IntegerArray) _index.get(value);
196     return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
197     }
198
199     /**
200      * Resets the iterator to the last start node.
201      */

202     public DTMAxisIterator reset() {
203     _position = 0;
204     return this;
205     }
206
207     /**
208      * Returns the number of elements in this iterator.
209      */

210     public int getLast() {
211     return (_nodes == null) ? 0 : _nodes.cardinality();
212     }
213
214     /**
215      * Returns the position of the current node in the set.
216      */

217     public int getPosition() {
218     return _position;
219     }
220
221     /**
222      * Remembers the current node for the next call to gotoMark().
223      */

224     public void setMark() {
225     _markedPosition = _position;
226     }
227
228     /**
229      * Restores the current node remembered by setMark().
230      */

231     public void gotoMark() {
232     _position = _markedPosition;
233     }
234
235     /**
236      * Set start to END should 'close' the iterator,
237      * i.e. subsequent call to next() should return END.
238      */

239     public DTMAxisIterator setStartNode(int start) {
240     if (start == DTMAxisIterator.END) {
241         _nodes = null;
242     }
243     else if (_nodes != null) {
244         _position = 0;
245     }
246     return (DTMAxisIterator) this;
247     }
248     
249     /**
250      * Get start to END should 'close' the iterator,
251      * i.e. subsequent call to next() should return END.
252      */

253     public int getStartNode() {
254         return 0;
255     }
256
257     /**
258      * True if this iterator has a reversed axis.
259      */

260     public boolean isReverse() {
261     return(false);
262     }
263
264     /**
265      * Returns a deep copy of this iterator.
266      */

267     public DTMAxisIterator cloneIterator() {
268     KeyIndex other = new KeyIndex(0);
269     other._index = _index;
270     other._nodes = _nodes;
271     other._position = _position;
272     return (DTMAxisIterator) other;
273     }
274     
275     public void setDom(DOM dom) {
276         _dom = dom;
277         if (dom instanceof DOMEnhancedForDTM) {
278             _enhancedDOM = (DOMEnhancedForDTM)dom;
279         }
280         else if (dom instanceof DOMAdapter) {
281             DOM idom = ((DOMAdapter)dom).getDOMImpl();
282             if (idom instanceof DOMEnhancedForDTM) {
283                 _enhancedDOM = (DOMEnhancedForDTM)idom;
284             }
285         }
286     }
287 }
288
Popular Tags