ProvidenceObjectParser.java
package net.morimekta.providence.client.google;
import com.google.api.client.util.ObjectParser;
import net.morimekta.providence.PMessage;
import net.morimekta.providence.descriptor.PMessageDescriptor;
import net.morimekta.providence.serializer.JsonSerializer;
import net.morimekta.providence.serializer.Serializer;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
/**
* Object parser for providence messages.
*/
public class ProvidenceObjectParser implements ObjectParser {
private final Serializer serializer;
public ProvidenceObjectParser(Serializer serializer) {
this.serializer = serializer;
}
@Nonnull
private PMessageDescriptor getMessageDescriptor(Class<?> aClass) {
try {
Field kDescriptor = aClass.getDeclaredField("kDescriptor");
return (PMessageDescriptor) kDescriptor.get(null);
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
throw new IllegalArgumentException("Class " + aClass.getName() + " is not a providence message", e);
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T parseAndClose(InputStream inputStream, Charset charset, Class<T> aClass) throws IOException {
try {
PMessageDescriptor descriptor = getMessageDescriptor(aClass);
return (T) serializer.deserialize(inputStream, descriptor);
} finally {
serializer.verifyEndOfContent(inputStream);
inputStream.close();
}
}
@Override
public Object parseAndClose(InputStream inputStream, Charset charset, Type type) throws IOException {
if (type instanceof Class && PMessage.class.isAssignableFrom((Class) type)) {
return parseAndClose(inputStream, charset, (Class<?>) type);
}
throw new IllegalArgumentException("Class " + type.getTypeName() + " is not a providence message");
}
@Override
@SuppressWarnings("unchecked")
public <T> T parseAndClose(Reader reader, Class<T> aClass) throws IOException {
if (serializer instanceof JsonSerializer) {
PMessageDescriptor descriptor = getMessageDescriptor(aClass);
JsonSerializer json = (JsonSerializer) serializer;
try {
return (T) json.deserialize(reader, descriptor);
} finally {
json.verifyEndOfContent(reader);
reader.close();
}
}
throw new IllegalStateException("Serializer " + serializer.toString() + " does not support Reader deserialization");
}
@Override
public Object parseAndClose(Reader reader, Type type) throws IOException {
if (type instanceof Class && PMessage.class.isAssignableFrom((Class) type)) {
return parseAndClose(reader, (Class<?>) type);
}
throw new IllegalArgumentException("Class " + type.getTypeName() + " is not a providence message");
}
}