XmlReader.java

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