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 (ArrayIndexOutOfBoundsException e) {
100			throw new IOException(
101					"xml parser mishandled ArrayIndexOufOfBounds", e);
102		} catch (StringIndexOutOfBoundsException e) {
103			throw new IOException(
104					"xml parser mishandled StringIndexOufOfBounds", e);
105		} catch (NullPointerException e) {
106			throw new IOException("xml parser mishandled NullPointerException",
107					e);
108		} catch (IndexOutOfBoundsException e) {
109			throw new IOException("xml parser mishandled IndexOutOfBound", e);
110		}
111		return null;
112	}
113
114	public Element readElement(Tag currentTag) throws XmlPullParserException,
115			IOException {
116		Element element = new Element(currentTag.getName());
117		element.setAttributes(currentTag.getAttributes());
118		Tag nextTag = this.readTag();
119		if (nextTag == null) {
120			throw new IOException("unterupted mid tag");
121		}
122		if (nextTag.isNo()) {
123			element.setContent(nextTag.getName());
124			nextTag = this.readTag();
125			if (nextTag == null) {
126				throw new IOException("unterupted mid tag");
127			}
128		}
129		while (!nextTag.isEnd(element.getName())) {
130			if (!nextTag.isNo()) {
131				Element child = this.readElement(nextTag);
132				element.addChild(child);
133			}
134			nextTag = this.readTag();
135			if (nextTag == null) {
136				throw new IOException("unterupted mid tag");
137			}
138		}
139		return element;
140	}
141}