1package eu.siacs.conversations.xml;
2
3import android.os.PowerManager;
4import android.os.PowerManager.WakeLock;
5import android.util.Log;
6import android.util.Xml;
7
8import org.xmlpull.v1.XmlPullParser;
9import org.xmlpull.v1.XmlPullParserException;
10
11import java.io.IOException;
12import java.io.InputStream;
13import java.io.InputStreamReader;
14
15import eu.siacs.conversations.Config;
16
17public class XmlReader {
18 private XmlPullParser parser;
19 private PowerManager.WakeLock wakeLock;
20 private InputStream is;
21
22 public XmlReader(WakeLock wakeLock) {
23 this.parser = Xml.newPullParser();
24 try {
25 this.parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,
26 true);
27 } catch (XmlPullParserException e) {
28 Log.d(Config.LOGTAG, "error setting namespace feature on parser");
29 }
30 this.wakeLock = wakeLock;
31 }
32
33 public void setInputStream(InputStream inputStream) throws IOException {
34 if (inputStream == null) {
35 throw new IOException();
36 }
37 this.is = inputStream;
38 try {
39 parser.setInput(new InputStreamReader(this.is));
40 } catch (XmlPullParserException e) {
41 throw new IOException("error resetting parser");
42 }
43 }
44
45 public InputStream getInputStream() throws IOException {
46 if (this.is == null) {
47 throw new IOException();
48 }
49 return is;
50 }
51
52 public void reset() throws IOException {
53 if (this.is == null) {
54 throw new IOException();
55 }
56 try {
57 parser.setInput(new InputStreamReader(this.is));
58 } catch (XmlPullParserException e) {
59 throw new IOException("error resetting parser");
60 }
61 }
62
63 public Tag readTag() throws XmlPullParserException, IOException {
64 if (wakeLock.isHeld()) {
65 try {
66 wakeLock.release();
67 } catch (RuntimeException re) {
68 }
69 }
70 try {
71 while (this.is != null
72 && parser.next() != XmlPullParser.END_DOCUMENT) {
73 wakeLock.acquire();
74 if (parser.getEventType() == XmlPullParser.START_TAG) {
75 Tag tag = Tag.start(parser.getName());
76 for (int i = 0; i < parser.getAttributeCount(); ++i) {
77 tag.setAttribute(parser.getAttributeName(i),
78 parser.getAttributeValue(i));
79 }
80 String xmlns = parser.getNamespace();
81 if (xmlns != null) {
82 tag.setAttribute("xmlns", xmlns);
83 }
84 return tag;
85 } else if (parser.getEventType() == XmlPullParser.END_TAG) {
86 Tag tag = Tag.end(parser.getName());
87 return tag;
88 } else if (parser.getEventType() == XmlPullParser.TEXT) {
89 Tag tag = Tag.no(parser.getText());
90 return tag;
91 }
92 }
93 if (wakeLock.isHeld()) {
94 try {
95 wakeLock.release();
96 } catch (RuntimeException re) {
97 }
98 }
99 } catch (Exception e) {
100 throw new IOException("xml parser mishandled "+e.getClass().getName(), e);
101 }
102 return null;
103 }
104
105 public Element readElement(Tag currentTag) throws XmlPullParserException,
106 IOException {
107 Element element = new Element(currentTag.getName());
108 element.setAttributes(currentTag.getAttributes());
109 Tag nextTag = this.readTag();
110 if (nextTag == null) {
111 throw new IOException("unterupted mid tag");
112 }
113 if (nextTag.isNo()) {
114 element.setContent(nextTag.getName());
115 nextTag = this.readTag();
116 if (nextTag == null) {
117 throw new IOException("unterupted mid tag");
118 }
119 }
120 while (!nextTag.isEnd(element.getName())) {
121 if (!nextTag.isNo()) {
122 Element child = this.readElement(nextTag);
123 element.addChild(child);
124 }
125 nextTag = this.readTag();
126 if (nextTag == null) {
127 throw new IOException("unterupted mid tag");
128 }
129 }
130 return element;
131 }
132}