// Path: src/main/java/nl/uva/larissa/json/model/Statement.java
// @JsonPropertyOrder({ "id", "actor", "verb", "object", "result", "context",
// 		"timestamp", "stored", "authority", "version" })
// @ValidRevisionUsage
// @ValidPlatformUsage
// public class Statement {
// 	@JsonProperty(required = false)
// 	@IsUUID
// 	private String id;
// 	@NotNull
// 	@Valid
// 	private Actor actor;
// 	@NotNull
// 	@Valid
// 	private Verb verb;
// 	@NotNull
// 	@Valid
// 	@JsonProperty("object")
// 	private StatementObject statementObject;
// 	private Result result;
// 	@Valid
// 	private Context context;
// 	// xAPI 1.0.1 4.1.7 A timestamp SHOULD be the current or a past time when it
// 	// is outside of a Sub-Statement.
// 	@Past
// 	private Date timestamp;
// 
// 	// should be set by the LRS, not the client
// 	@Null
// 	private Date stored;
// 	private Authority authority;
// 	private String version;
// 
// 	public String getId() {
// 		return id;
// 	}
// 
// 	public void setId(String id) {
// 		this.id = id;
// 	}
// 
// 	public Actor getActor() {
// 		return actor;
// 	}
// 
// 	public void setActor(Actor actor) {
// 		this.actor = actor;
// 	}
// 
// 	public Verb getVerb() {
// 		return verb;
// 	}
// 
// 	public void setVerb(Verb verb) {
// 		this.verb = verb;
// 	}
// 
// 	public StatementObject getStatementObject() {
// 		return statementObject;
// 	}
// 
// 	public void setStatementObject(StatementObject statementObject) {
// 		this.statementObject = statementObject;
// 	}
// 
// 	public Result getResult() {
// 		return result;
// 	}
// 
// 	public void setResult(Result result) {
// 		this.result = result;
// 	}
// 
// 	public Date getTimestamp() {
// 		return timestamp;
// 	}
// 
// 	public void setTimestamp(Date timestamp) {
// 		this.timestamp = timestamp;
// 	}
// 
// 	public Date getStored() {
// 		return stored;
// 	}
// 
// 	public void setStored(Date stored) {
// 		this.stored = stored;
// 	}
// 
// 	public Authority getAuthority() {
// 		return authority;
// 	}
// 
// 	public void setAuthority(Authority authority) {
// 		this.authority = authority;
// 	}
// 
// 	public String getVersion() {
// 		return version;
// 	}
// 
// 	public void setVersion(String version) {
// 		this.version = version;
// 	}
// 
// 	public Context getContext() {
// 		return context;
// 	}
// 
// 	public void setContext(Context context) {
// 		this.context = context;
// 	}
// }
// 
// Path: src/main/java/nl/uva/larissa/repository/couchdb/StatementDocument.java
// public class StatementDocument extends CouchDbDocument {
// 
// 	public static enum Type {
// 		PLAIN, VOIDED
// 	}
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1533055980737805979L;
// 
// 	@JsonUnwrapped
// 	private Statement statement;
// 
// 	private Type type = Type.PLAIN;
// 
// 	private List<StatementDocument> referrers = new ArrayList<>();
// 	
// 	public List<StatementDocument> getReferrers() {
// 		return referrers;
// 	}
// 
// 	public void setReferrers(List<StatementDocument> referrers) {
// 		this.referrers = referrers;
// 	}
// 
// 	public Statement getStatement() {
// 		return statement;
// 	}
// 
// 	public void setStatement(Statement statement) {
// 		this.statement = statement;
// 	}
// 
// 	public Type getType() {
// 		return type;
// 	}
// 
// 	public void setType(Type type) {
// 		this.type = type;
// 	}
// 
// }


import java.io.IOException;
import java.util.List;
import org.apache.abdera.i18n.iri.IRI;
import nl.uva.larissa.json.model.Statement;
import nl.uva.larissa.repository.couchdb.StatementDocument;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
package nl.uva.larissa.json;





public class StatementParserImpl implements StatementParser {

	final private ObjectMapper mapper;

	public StatementParserImpl() {
		this.mapper = new ObjectMapper();
		// FIXME Jackson doesn't seem to give an error on a missing property on
		// the level of an ActivityDefinition. This is potentially risky as a
		// statement will
		// be accepted yet stored incomplete. bug in Jackson?
		// TODO make this configure less general? (meant for only
		// ContextActivities)
		mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
				true);
		SimpleModule module = new SimpleModule();
		module.addDeserializer(IRI.class, new IRIDeserializer());
		mapper.registerModule(module);
	}

	@Override
	public Statement parseStatement(String json) throws ParseException {
		try {
			Statement result = mapper.readValue(json, Statement.class);
			if (result == null) {
				throw new ParseException("no data");
			}
			return result;
		} catch (IOException e) {
			throw new ParseException(e);
		}
	}

	@Override
// Path: src/main/java/nl/uva/larissa/json/model/Statement.java
// @JsonPropertyOrder({ "id", "actor", "verb", "object", "result", "context",
// 		"timestamp", "stored", "authority", "version" })
// @ValidRevisionUsage
// @ValidPlatformUsage
// public class Statement {
// 	@JsonProperty(required = false)
// 	@IsUUID
// 	private String id;
// 	@NotNull
// 	@Valid
// 	private Actor actor;
// 	@NotNull
// 	@Valid
// 	private Verb verb;
// 	@NotNull
// 	@Valid
// 	@JsonProperty("object")
// 	private StatementObject statementObject;
// 	private Result result;
// 	@Valid
// 	private Context context;
// 	// xAPI 1.0.1 4.1.7 A timestamp SHOULD be the current or a past time when it
// 	// is outside of a Sub-Statement.
// 	@Past
// 	private Date timestamp;
// 
// 	// should be set by the LRS, not the client
// 	@Null
// 	private Date stored;
// 	private Authority authority;
// 	private String version;
// 
// 	public String getId() {
// 		return id;
// 	}
// 
// 	public void setId(String id) {
// 		this.id = id;
// 	}
// 
// 	public Actor getActor() {
// 		return actor;
// 	}
// 
// 	public void setActor(Actor actor) {
// 		this.actor = actor;
// 	}
// 
// 	public Verb getVerb() {
// 		return verb;
// 	}
// 
// 	public void setVerb(Verb verb) {
// 		this.verb = verb;
// 	}
// 
// 	public StatementObject getStatementObject() {
// 		return statementObject;
// 	}
// 
// 	public void setStatementObject(StatementObject statementObject) {
// 		this.statementObject = statementObject;
// 	}
// 
// 	public Result getResult() {
// 		return result;
// 	}
// 
// 	public void setResult(Result result) {
// 		this.result = result;
// 	}
// 
// 	public Date getTimestamp() {
// 		return timestamp;
// 	}
// 
// 	public void setTimestamp(Date timestamp) {
// 		this.timestamp = timestamp;
// 	}
// 
// 	public Date getStored() {
// 		return stored;
// 	}
// 
// 	public void setStored(Date stored) {
// 		this.stored = stored;
// 	}
// 
// 	public Authority getAuthority() {
// 		return authority;
// 	}
// 
// 	public void setAuthority(Authority authority) {
// 		this.authority = authority;
// 	}
// 
// 	public String getVersion() {
// 		return version;
// 	}
// 
// 	public void setVersion(String version) {
// 		this.version = version;
// 	}
// 
// 	public Context getContext() {
// 		return context;
// 	}
// 
// 	public void setContext(Context context) {
// 		this.context = context;
// 	}
// }
// 
// Path: src/main/java/nl/uva/larissa/repository/couchdb/StatementDocument.java
// public class StatementDocument extends CouchDbDocument {
// 
// 	public static enum Type {
// 		PLAIN, VOIDED
// 	}
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1533055980737805979L;
// 
// 	@JsonUnwrapped
// 	private Statement statement;
// 
// 	private Type type = Type.PLAIN;
// 
// 	private List<StatementDocument> referrers = new ArrayList<>();
// 	
// 	public List<StatementDocument> getReferrers() {
// 		return referrers;
// 	}
// 
// 	public void setReferrers(List<StatementDocument> referrers) {
// 		this.referrers = referrers;
// 	}
// 
// 	public Statement getStatement() {
// 		return statement;
// 	}
// 
// 	public void setStatement(Statement statement) {
// 		this.statement = statement;
// 	}
// 
// 	public Type getType() {
// 		return type;
// 	}
// 
// 	public void setType(Type type) {
// 		this.type = type;
// 	}
// 
// }


// Path: src/main/java/nl/uva/larissa/json/StatementParserImpl.java
import java.io.IOException;
import java.util.List;
import org.apache.abdera.i18n.iri.IRI;
import nl.uva.larissa.json.model.Statement;
import nl.uva.larissa.repository.couchdb.StatementDocument;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

package nl.uva.larissa.json;





public class StatementParserImpl implements StatementParser {

	final private ObjectMapper mapper;

	public StatementParserImpl() {
		this.mapper = new ObjectMapper();
		// FIXME Jackson doesn't seem to give an error on a missing property on
		// the level of an ActivityDefinition. This is potentially risky as a
		// statement will
		// be accepted yet stored incomplete. bug in Jackson?
		// TODO make this configure less general? (meant for only
		// ContextActivities)
		mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
				true);
		SimpleModule module = new SimpleModule();
		module.addDeserializer(IRI.class, new IRIDeserializer());
		mapper.registerModule(module);
	}

	@Override
	public Statement parseStatement(String json) throws ParseException {
		try {
			Statement result = mapper.readValue(json, Statement.class);
			if (result == null) {
				throw new ParseException("no data");
			}
			return result;
		} catch (IOException e) {
			throw new ParseException(e);
		}
	}

	@Override
	public StatementDocument parseStatementDocument(String json)