XmlReader.java

  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}