/*
* VersionHistoryParser.java
* Copyright (C) 2015 Nicholas Killewald
*
* This file is distributed under the terms of the BSD license.
* The source package should have a LICENSE file at the toplevel.
*/
package net.exclaimindustries.geohashdroid.util;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import net.exclaimindustries.geohashdroid.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
/**
* The <code>VersionHistoryParser</code> parses the version history XML file
* (obviously) and puts its contents into a nice class for simple reading later.
*/
public class VersionHistoryParser {
/**
* A <code>VersionEntry</code> holds a single entry in the version history
* (obviously). You will generally get a List of these.
*/
public static class VersionEntry implements Parcelable {
public VersionEntry() { }
private VersionEntry(Parcel in) {
// Oh, hey, we're Parcelable now. Who would've guessed?
readFromParcel(in);
}
public static final Parcelable.Creator<VersionEntry> CREATOR = new Parcelable.Creator<VersionEntry>() {
@Override
public VersionEntry createFromParcel(Parcel source) { return new VersionEntry(source); }
@Override
public VersionEntry[] newArray(int size) { return new VersionEntry[size]; }
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// Dump 'em out!
dest.writeString(title);
dest.writeString(versionName);
dest.writeString(date);
dest.writeInt(versionCode);
dest.writeString(header);
dest.writeString(footer);
dest.writeStringList(bullets);
}
public void readFromParcel(Parcel in) {
// Fill 'em back in!
title = in.readString();
versionName = in.readString();
date = in.readString();
versionCode = in.readInt();
header = in.readString();
footer = in.readString();
bullets = in.createStringArrayList();
}
/**
* The title of this version. Can be empty. Will generally be whatever
* silly name I decided to give it.
*/
@NonNull public String title = "";
/**
* The "name" of this version. That is, something like "0.9.0-pre1".
* Must never be empty.
*/
@NonNull public String versionName = "";
/**
* The date this version was released, as an XML standard formatted date
* string (i.e. 2015-08-30). Make your own damn Calendar object if you
* really want that.
*/
@NonNull public String date = "";
/**
* The internal version code of this version. That is, whatever the
* manifest actually uses for version identification.
*/
public int versionCode = 0;
/**
* The header of this version. This is some descriptive text that comes
* before the bullets.
*/
@NonNull public String header = "";
/**
* The footer of this version. This is some descriptive text that comes
* after the bullets.
*/
@NonNull public String footer = "";
/**
* The list of bullet entries. Each of these should be displayed in
* order in their own section, indented and with bullets on the side.
*/
@NonNull public ArrayList<String> bullets = new ArrayList<>();
@Override
public String toString() {
return "Version history entry, version " + versionName + " (" + versionCode + "), contains " + bullets.size() + " bullet(s)";
}
}
/**
* Parses out the version history and returns an array of entries.
*
* @param c a Context for resources
* @return a bunch of VersionHistoryEntries
* @throws XmlPullParserException something went wrong with XML parsing
*/
public static ArrayList<VersionEntry> parseVersionHistory(Context c) throws XmlPullParserException {
ArrayList<VersionEntry> toReturn = new ArrayList<>();
// To the parser!
XmlResourceParser xrp = c.getResources().getXml(R.xml.version_history);
int eventType = xrp.getEventType();
String currentTag = "";
VersionEntry currentEntry = null;
while(eventType != XmlPullParser.END_DOCUMENT) {
// There's only a few events we can get, so...
if(eventType == XmlPullParser.START_TAG) {
// Okay... so, what tag is it?
currentTag = xrp.getName();
if(currentTag.equals("version")) {
// New version! This means we get a new entry!
currentEntry = new VersionEntry();
// There's also a few attributes in a version. Like so:
currentEntry.versionName = xrp.getAttributeValue(null, "name");
currentEntry.date = xrp.getAttributeValue(null, "date");
currentEntry.versionCode = Integer.parseInt(xrp.getAttributeValue(null, "version"));
}
} else if (eventType == XmlPullParser.TEXT) {
// On text, we feed data in depending on what tag started to get
// us here in the first place.
if(currentEntry == null) {
throw new RuntimeException("The current entry is null and we're in text parsing!");
}
switch(currentTag) {
case "title":
currentEntry.title = xrp.getText();
break;
case "header":
currentEntry.header = xrp.getText();
break;
case "footer":
currentEntry.footer = xrp.getText();
break;
case "bullet":
// Ah, but a bullet? That gets added to a list instead.
currentEntry.bullets.add(xrp.getText());
break;
}
} else if(eventType == XmlPullParser.END_TAG) {
if(xrp.getName().equals("version")) {
// End of a version! It can go into toReturn.
toReturn.add(currentEntry);
}
}
try {
eventType = xrp.next();
} catch(IOException ioe) {
throw new RuntimeException("An IOException occurred during XML parsing!");
}
}
// And we're done!
xrp.close();
return toReturn;
}
}