KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtworks > xstream > io > xml > AbstractPullReader


1 package com.thoughtworks.xstream.io.xml;
2
3 import com.thoughtworks.xstream.core.util.FastStack;
4 import com.thoughtworks.xstream.io.AttributeNameIterator;
5 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
6
7 import java.util.Iterator JavaDoc;
8
9 /**
10  * Base class that contains common functionality across HierarchicalStreamReader implementations
11  * that need to read from a pull parser.
12  *
13  * @author Joe Walnes
14  * @author James Strachan
15  */

16 public abstract class AbstractPullReader implements HierarchicalStreamReader {
17
18     protected static final int START_NODE = 1;
19     protected static final int END_NODE = 2;
20     protected static final int TEXT = 3;
21     protected static final int COMMENT = 4;
22     protected static final int OTHER = 0;
23
24     private final FastStack elementStack = new FastStack(16);
25
26     private final FastStack lookahead = new FastStack(4);
27     private final FastStack lookback = new FastStack(4);
28     private boolean marked;
29
30     private static class Event {
31         int type;
32         String JavaDoc value;
33     }
34
35     /**
36      * Pull the next event from the stream.
37      *
38      * <p>This MUST return {@link #START_NODE}, {@link #END_NODE}, {@link #TEXT}, {@link #COMMENT},
39      * {@link #OTHER} or throw {@link com.thoughtworks.xstream.io.StreamException}.</p>
40      *
41      * <p>The underlying pull parser will most likely return its own event types. These must be
42      * mapped to the appropriate events.</p>
43      */

44     protected abstract int pullNextEvent();
45
46     /**
47      * Pull the name of the current element from the stream.
48      */

49     protected abstract String JavaDoc pullElementName();
50
51     /**
52      * Pull the contents of the current text node from the stream.
53      */

54     protected abstract String JavaDoc pullText();
55
56     public boolean hasMoreChildren() {
57         mark();
58         while (true) {
59             switch (readEvent().type) {
60                 case START_NODE:
61                     reset();
62                     return true;
63                 case END_NODE:
64                     reset();
65                     return false;
66                 default:
67                     continue;
68             }
69         }
70     }
71
72     public void moveDown() {
73         int currentDepth = elementStack.size();
74         while (elementStack.size() <= currentDepth) {
75             move();
76             if (elementStack.size() < currentDepth) {
77                 throw new RuntimeException JavaDoc(); // sanity check
78
}
79         }
80     }
81
82     public void moveUp() {
83         int currentDepth = elementStack.size();
84         while (elementStack.size() >= currentDepth) {
85             move();
86         }
87     }
88
89     private void move() {
90         switch (readEvent().type) {
91             case START_NODE:
92                 elementStack.push(pullElementName());
93                 break;
94             case END_NODE:
95                 elementStack.pop();
96                 break;
97         }
98     }
99
100     private Event readEvent() {
101         if (marked) {
102             if (lookback.hasStuff()) {
103                 return (Event) lookahead.push(lookback.pop());
104             } else {
105                 return (Event) lookahead.push(readRealEvent());
106             }
107         } else {
108             if (lookback.hasStuff()) {
109                 return (Event) lookback.pop();
110             } else {
111                 return readRealEvent();
112             }
113         }
114     }
115
116     private Event readRealEvent() {
117         Event event = new Event();
118         event.type = pullNextEvent();
119         if (event.type == TEXT) {
120             event.value = pullText();
121         } else if (event.type == START_NODE) {
122             event.value = pullElementName();
123         }
124         return event;
125     }
126
127     public void mark() {
128         marked = true;
129     }
130
131     public void reset() {
132         while(lookahead.hasStuff()) {
133             lookback.push(lookahead.pop());
134         }
135         marked = false;
136     }
137
138     public String JavaDoc getValue() {
139         // we should collapse together any text which
140
// contains comments
141

142         // lets only use a string buffer when we get 2 strings
143
// to avoid copying strings
144
String JavaDoc last = null;
145         StringBuffer JavaDoc buffer = null;
146
147         mark();
148         Event event = readEvent();
149         while (true) {
150             if (event.type == TEXT) {
151                 String JavaDoc text = event.value;
152                 if (text != null && text.length() > 0) {
153                     if (last == null) {
154                         last = text;
155                     } else {
156                         if (buffer == null) {
157                             buffer = new StringBuffer JavaDoc(last);
158                         }
159                         buffer.append(text);
160                     }
161                 }
162             } else if (event.type != COMMENT) {
163                 break;
164             }
165             event = readEvent();
166         }
167         reset();
168         if (buffer != null) {
169             return buffer.toString();
170         } else {
171             return (last == null) ? "" : last;
172         }
173     }
174
175     public Iterator getAttributeNames() {
176         return new AttributeNameIterator(this);
177     }
178
179     public String JavaDoc getNodeName() {
180         return (String JavaDoc) elementStack.peek();
181     }
182
183     public Object JavaDoc peekUnderlyingNode() {
184         throw new UnsupportedOperationException JavaDoc();
185     }
186
187     public HierarchicalStreamReader underlyingReader() {
188         return this;
189     }
190
191 }
192
Popular Tags