package org.dodgybits.shuffle.android.synchronisation.tracks.parsing;
import static org.dodgybits.shuffle.android.core.util.Constants.cFlurryTracksSyncError;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import org.dodgybits.shuffle.android.core.activity.flurry.Analytics;
import org.dodgybits.shuffle.android.core.model.EntityBuilder;
import org.dodgybits.shuffle.android.core.model.Id;
import org.dodgybits.shuffle.android.synchronisation.tracks.TracksEntities;
import org.dodgybits.shuffle.android.synchronisation.tracks.model.TracksEntity;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.Log;
import android.util.Xml;
public abstract class Parser<E extends TracksEntity> {
private static final String cTag = "Parser";
protected HashMap<String, Applier> appliers;
private String mEntityName;
private Analytics mAnalytics;
public Parser(String entityName, Analytics analytics) {
appliers = new HashMap<String, Applier>();
mEntityName = entityName;
mAnalytics = analytics;
}
public TracksEntities<E> parseDocument(String tracksEntityXml) {
Map<Id, E> entities = new HashMap<Id, E>();
boolean errorFree = true;
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(new StringReader(tracksEntityXml));
int eventType = parser.getEventType();
boolean done = false;
while (eventType != XmlPullParser.END_DOCUMENT && !done) {
ParseResult<E> result = null;
try {
result = parseSingle(parser);
} catch (Exception e) {
logTracksError(e);
errorFree = false;
}
if(!result.IsSuccess()) {
errorFree = false;
}
E entity = result.getResult();
if (entity != null && entity.isValid()) {
entities.put(entity.getTracksId(), entity);
}
eventType = parser.getEventType();
String name = parser.getName();
if (eventType == XmlPullParser.END_TAG &&
name.equalsIgnoreCase(endIndexTag())) {
done = true;
}
}
} catch (XmlPullParserException e) {
logTracksError(e);
errorFree = false;
}
return new TracksEntities<E>(entities, errorFree);
}
private void logTracksError(Exception e) {
Log.e(cTag, "Failed to parse " + endIndexTag() + " " + e.getMessage());
mAnalytics.onError(cFlurryTracksSyncError, e.getMessage(), getClass().getName());
}
private String endIndexTag() {
return this.mEntityName + "s";
}
public ParseResult<E> parseSingle(XmlPullParser parser) {
EntityBuilder<E> builder = createBuilder();
E entity = null;
boolean success = true;
try {
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT && entity == null) {
String name = parser.getName();
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
Applier applier = appliers.get(name);
if(applier != null) {
success &= applier.apply(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if (name.equalsIgnoreCase(mEntityName)) {
entity = builder.build();
}
break;
}
eventType = parser.next();
}
} catch (IOException e) {
Log.d("Exception", "IO EXception", e);
return new ParseResult<E>();
} catch (XmlPullParserException e) {
Log.d("Exception", "pullparser exception", e);
return new ParseResult<E>();
}
return new ParseResult<E>(entity, success);
}
protected abstract EntityBuilder<E> createBuilder();
}