com.regnosys.rosetta.translate.CustomDeserialise Maven / Gradle / Ivy
package com.regnosys.rosetta.translate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class CustomDeserialise {
protected Map> parseMethods = new HashMap<>();
public CustomDeserialise() {
}
public Object deserialise(InputStream in) throws ParseException {
DeserialiseContext context = new DeserialiseContext(new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)));
return readOne(context);
}
protected T readOne(DeserialiseContext context) {
String line = context.read();
if (line.startsWith("null")) {
return null;
}
return readOne(line, context);
}
@SuppressWarnings("unchecked")
private T readOne(String firstLine, DeserialiseContext context) {
T o = null;
// this is a reference to an object that will be defined somewhere higher in the file
if (firstLine.startsWith("=")) {
Long objectId = Long.parseLong(firstLine.substring(1));
o = (T) context.objectIds.get(objectId);
if (o == null) {
throw new ParseException("Object with id " + objectId + " not found at line " + context.lineNum);
}
} else if (firstLine.startsWith("#")) {
// this is the definition of an object
Long objectId = Long.parseLong(firstLine.substring(1));
String className = context.read("class:");
o = readObject(className, objectId, context);
} else {
throw new ParseException("Expecting Array end ']' object start '#num' or reference '=num' but found " + firstLine + " at line " + context.lineNum);
}
return o;
}
protected List readList(DeserialiseContext context) {
List result = new ArrayList<>();
boolean arrayEnd = false;
while (!arrayEnd) {
String line = context.read();
if (line.startsWith("null")) {
// TODO document me
} else if (line.startsWith("]")) {
arrayEnd = true;
} else {
T o = readOne(line, context);
result.add(o);
}
}
return result;
}
@SuppressWarnings("unchecked")
private T readObject(String className, long objectId, DeserialiseContext context) {
BiFunction parseMethod = parseMethods.get(className);
if (parseMethod == null) {
throw new ParseException("Dont know how to read object of type " + className + " at line " + context.lineNum);
}
return (T) parseMethod.apply(objectId, context);
}
protected class DeserialiseContext {
private final BufferedReader reader;
private final Map objectIds = new HashMap<>();
private int lineNum = 0;
public DeserialiseContext(BufferedReader reader) {
super();
this.reader = reader;
}
public String read(String expected) {
String read = read();
if (!read.startsWith(expected)) {
throw new ParseException("Error reading schema at line " + lineNum + " expected " + expected + " but read " + read);
}
return read.substring(expected.length());
}
public void addObjectId(Long objectId, Object object) {
objectIds.put(objectId, object);
}
protected String read() {
try {
String read = reader.readLine().trim();
lineNum++;
return read;
} catch (IOException e) {
throw new ParseException("error reading from source", e);
}
}
}
public class ParseException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ParseException(String message, Exception cause) {
super(message, cause);
}
public ParseException(String message) {
super(message);
}
}
}