01: package net.sf.saxon.pull;
02:
03: import net.sf.saxon.trans.XPathException;
04:
05: /**
06: * This is a filter that can be added to a pull pipeline to remember element names so that
07: * they are available immediately after the END_ELEMENT event is notified
08: */
09: public class ElementNameTracker extends PullFilter {
10:
11: private int[] namestack = new int[20];
12: int used = 0;
13: int elementJustEnded = -1;
14:
15: public ElementNameTracker(PullProvider base) {
16: super (base);
17: }
18:
19: /**
20: * Get the next event.
21: * <p/>
22: * <p>Note that a subclass that overrides this method is responsible for ensuring
23: * that current() works properly. This can be achieved by setting the field
24: * currentEvent to the event returned by any call on next().</p>
25: *
26: * @return an integer code indicating the type of event. The code
27: * {@link #END_OF_INPUT} is returned at the end of the sequence.
28: */
29:
30: public int next() throws XPathException {
31: currentEvent = super .next();
32: if (currentEvent == START_ELEMENT) {
33: int nc = getNameCode();
34: if (used >= namestack.length) {
35: int[] n2 = new int[used * 2];
36: System.arraycopy(namestack, 0, n2, 0, used);
37: namestack = n2;
38: }
39: namestack[used++] = nc;
40: } else if (currentEvent == END_ELEMENT) {
41: elementJustEnded = namestack[--used];
42: }
43: return currentEvent;
44: }
45:
46: /**
47: * Get the nameCode identifying the name of the current node. This method
48: * can be used after the {@link #START_ELEMENT}, {@link #PROCESSING_INSTRUCTION},
49: * {@link #ATTRIBUTE}, or {@link #NAMESPACE} events. With some PullProvider implementations,
50: * including this one, it can also be used after {@link #END_ELEMENT}: in fact, that is the
51: * main purpose of this class.
52: * If called at other times, the result is undefined and may result in an IllegalStateException.
53: * If called when the current node is an unnamed namespace node (a node representing the default namespace)
54: * the returned value is -1.
55: *
56: * @return the nameCode. The nameCode can be used to obtain the prefix, local name,
57: * and namespace URI from the name pool.
58: */
59:
60: public int getNameCode() {
61: if (currentEvent == END_ELEMENT) {
62: return elementJustEnded;
63: } else {
64: return super .getNameCode();
65: }
66: }
67: }
68:
69: //
70: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
71: // you may not use this file except in compliance with the License. You may obtain a copy of the
72: // License at http://www.mozilla.org/MPL/
73: //
74: // Software distributed under the License is distributed on an "AS IS" basis,
75: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
76: // See the License for the specific language governing rights and limitations under the License.
77: //
78: // The Original Code is: all this file.
79: //
80: // The Initial Developer of the Original Code is Michael H. Kay.
81: //
82: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
83: //
84: // Contributor(s): none.
85: //
|