KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.thoughtworks.xstream.io.xml;
2
3 import com.thoughtworks.xstream.converters.ErrorWriter;
4 import com.thoughtworks.xstream.core.util.IntQueue;
5 import com.thoughtworks.xstream.core.util.StringStack;
6 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
7 import com.thoughtworks.xstream.io.StreamException;
8 import org.xmlpull.mxp1.MXParser;
9 import org.xmlpull.v1.XmlPullParser;
10 import org.xmlpull.v1.XmlPullParserException;
11
12 import java.io.BufferedReader JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.Reader JavaDoc;
15
16 public class XppReader implements HierarchicalStreamReader {
17
18     private final XmlPullParser parser;
19     private final StringStack elementStack = new StringStack(16);
20     private final IntQueue lookaheadQueue = new IntQueue(4);
21
22     public XppReader(Reader reader) {
23         try {
24             parser = createParser();
25             parser.setInput(new BufferedReader JavaDoc(reader));
26             moveDown();
27         } catch (XmlPullParserException e) {
28             throw new StreamException(e);
29         }
30     }
31
32     protected XmlPullParser createParser() {
33         // WARNING, read comment in getValue() before switching
34
// to a different parser.
35
return new MXParser();
36     }
37
38     public boolean hasMoreChildren() {
39         while (true) {
40             switch (lookahead()) {
41                 case XmlPullParser.START_TAG:
42                     return true;
43                 case XmlPullParser.END_TAG:
44                 case XmlPullParser.END_DOCUMENT:
45                     return false;
46                 default:
47                     continue;
48             }
49         }
50     }
51
52     private int lookahead() {
53         try {
54             int event = parser.next();
55             lookaheadQueue.write(event);
56             return event;
57         } catch (XmlPullParserException e) {
58             throw new StreamException(e);
59         } catch (IOException JavaDoc e) {
60             throw new StreamException(e);
61         }
62     }
63
64     private int next() {
65         if (!lookaheadQueue.isEmpty()) {
66             return lookaheadQueue.read();
67         } else {
68             try {
69                 return parser.next();
70             } catch (XmlPullParserException e) {
71                 throw new StreamException(e);
72             } catch (IOException JavaDoc e) {
73                 throw new StreamException(e);
74             }
75         }
76     }
77
78     public void moveDown() {
79         int currentDepth = elementStack.size();
80         while (elementStack.size() <= currentDepth) {
81             read();
82             if (elementStack.size() < currentDepth) {
83                 throw new RuntimeException JavaDoc(); // sanity check
84
}
85         }
86     }
87
88     public void moveUp() {
89         int currentDepth = elementStack.size();
90         while (elementStack.size() >= currentDepth) {
91             read();
92         }
93     }
94
95     public String JavaDoc getNodeName() {
96         return elementStack.peek();
97     }
98
99     public String JavaDoc getValue() {
100         // MXP1 (pull parser) collapses all text into a single
101
// text event. This allows us to only need to lookahead
102
// one step. However if using a different pull parser
103
// impl, you may need to look ahead further.
104
if (lookahead() == XmlPullParser.TEXT) {
105             String JavaDoc text = parser.getText();
106             return text == null ? "" : text;
107         } else {
108             return "";
109         }
110     }
111
112     public String JavaDoc getAttribute(String JavaDoc name) {
113         return parser.getAttributeValue(null, name);
114     }
115
116     public Object JavaDoc peekUnderlyingNode() {
117         throw new UnsupportedOperationException JavaDoc();
118     }
119
120     private void read() {
121         switch (next()) {
122             case XmlPullParser.START_TAG:
123                 elementStack.push(parser.getName());
124                 break;
125             case XmlPullParser.END_TAG:
126             case XmlPullParser.END_DOCUMENT:
127                 elementStack.pop();
128                 break;
129         }
130     }
131
132     public void appendErrors(ErrorWriter errorWriter) {
133         errorWriter.add("line number", String.valueOf(parser.getLineNumber()));
134     }
135 }
Popular Tags