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(this.is != null && 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		} catch (StringIndexOutOfBoundsException e) {
 83			throw new IOException("xml parser mishandled StringIndexOufOfBounds", e);
 84		}
 85		return null;
 86	}
 87
 88	public Element readElement(Tag currentTag) throws XmlPullParserException, IOException {
 89		Element element = new Element(currentTag.getName());
 90		element.setAttributes(currentTag.getAttributes());
 91		Tag nextTag = this.readTag();
 92		if (nextTag == null) {
 93			throw new IOException("unterupted mid tag");
 94		}
 95		if(nextTag.isNo()) {
 96			element.setContent(nextTag.getName());
 97			nextTag = this.readTag();
 98			if (nextTag == null) {
 99				throw new IOException("unterupted mid tag");
100			}
101		}
102		while(!nextTag.isEnd(element.getName())) {
103			if (!nextTag.isNo()) {
104				Element child = this.readElement(nextTag);
105				element.addChild(child);
106			}
107			nextTag = this.readTag();
108			if (nextTag == null) {
109				throw new IOException("unterupted mid tag");
110			}
111		}
112		return element;
113	}
114}