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) {
 32		this.is = inputStream;
 33		try {
 34			parser.setInput(new InputStreamReader(this.is));
 35		} catch (XmlPullParserException e) {
 36			Log.d(LOGTAG,"error setting input stream");
 37		}
 38	}
 39
 40	public InputStream getInputStream() {
 41		return is;
 42	}
 43
 44	public void reset() {
 45		try {
 46			parser.setInput(new InputStreamReader(this.is));
 47		} catch (XmlPullParserException e) {
 48			Log.d(LOGTAG,"error resetting input stream");
 49		}
 50	}
 51	
 52	public Tag readTag() throws XmlPullParserException, IOException {
 53		if (wakeLock.isHeld()) {
 54			try { wakeLock.release();} catch (RuntimeException re) {}
 55		}
 56		try {
 57			while(parser.next() != XmlPullParser.END_DOCUMENT) {
 58					wakeLock.acquire();
 59					if (parser.getEventType() == XmlPullParser.START_TAG) {
 60						Tag tag = Tag.start(parser.getName());
 61						for(int i = 0; i < parser.getAttributeCount(); ++i) {
 62							tag.setAttribute(parser.getAttributeName(i), parser.getAttributeValue(i));
 63						}
 64						String xmlns = 	parser.getNamespace();
 65						if (xmlns!=null) {
 66							tag.setAttribute("xmlns",xmlns);
 67						}
 68						return tag;
 69					} else if (parser.getEventType() == XmlPullParser.END_TAG) {
 70						Tag tag = Tag.end(parser.getName());
 71						return tag;
 72					} else if (parser.getEventType() == XmlPullParser.TEXT) {
 73						Tag tag = Tag.no(parser.getText());
 74						return tag;
 75					}
 76				}
 77			if (wakeLock.isHeld()) {
 78				try { wakeLock.release();} catch (RuntimeException re) {}
 79			}
 80		} catch (ArrayIndexOutOfBoundsException e) {
 81			throw new IOException("xml parser mishandled ArrayIndexOufOfBounds", e);
 82		}
 83		return null;
 84	}
 85
 86	public Element readElement(Tag currentTag) throws XmlPullParserException, IOException {
 87		Element element = new Element(currentTag.getName());
 88		element.setAttributes(currentTag.getAttributes());
 89		Tag nextTag = this.readTag();
 90		if(nextTag.isNo()) {
 91			element.setContent(nextTag.getName());
 92			nextTag = this.readTag();
 93		}
 94		if (nextTag == null) {
 95			throw new IOException("unterupted mid tag");
 96		}
 97		while(!nextTag.isEnd(element.getName())) {
 98			if (!nextTag.isNo()) {
 99				Element child = this.readElement(nextTag);
100				element.addChild(child);
101			}
102			nextTag = this.readTag();
103			if (nextTag == null) {
104				throw new IOException("unterupted mid tag");
105			}
106		}
107		return element;
108	}
109}