use of net.morimekta.providence.descriptor.PMessageDescriptor in project providence by morimekta.
the class ProvidenceMessageBodyReader method getDescriptor.
@Nullable
private PMessageDescriptor getDescriptor(Class<?> type) {
try {
if (!PMessage.class.isAssignableFrom(type)) {
return null;
}
Field descField = type.getDeclaredField("kDescriptor");
Object desc = descField.get(null);
if (desc instanceof PMessageDescriptor) {
return (PMessageDescriptor) desc;
}
} catch (NoSuchFieldException | IllegalAccessException ignore) {
// ignore.printStackTrace();
}
return null;
}
use of net.morimekta.providence.descriptor.PMessageDescriptor in project providence by morimekta.
the class MessageRowMapper method map.
@Override
public M map(int idx, ResultSet rs, StatementContext ctx) throws SQLException {
PMessageBuilder<M, F> builder = descriptor.builder();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); ++i) {
if (!tableName.isEmpty() && !tableName.equalsIgnoreCase(rs.getMetaData().getTableName(i))) {
continue;
}
String name = rs.getMetaData().getColumnLabel(i).toUpperCase(Locale.US);
F field = fieldNameMapping.get(name);
if (field != null) {
int columnType = rs.getMetaData().getColumnType(i);
switch(field.getType()) {
case BOOL:
{
if (columnType == Types.BOOLEAN || columnType == Types.BIT) {
boolean b = rs.getBoolean(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
} else {
int b = rs.getInt(i);
if (!rs.wasNull()) {
builder.set(field, b != 0);
}
}
break;
}
case BYTE:
{
byte b = rs.getByte(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
break;
}
case I16:
{
short b = rs.getShort(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
break;
}
case I32:
{
if (columnType == Types.TIMESTAMP) {
Timestamp ts = rs.getTimestamp(i);
if (ts != null) {
builder.set(field, (int) (ts.getTime() / 1000L));
}
} else {
int b = rs.getInt(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
}
break;
}
case I64:
{
if (columnType == Types.TIMESTAMP) {
Timestamp ts = rs.getTimestamp(i);
if (ts != null) {
builder.set(field, ts.getTime());
}
} else {
long b = rs.getLong(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
}
break;
}
case DOUBLE:
{
double b = rs.getDouble(i);
if (!rs.wasNull()) {
builder.set(field, b);
}
break;
}
case STRING:
{
builder.set(field, rs.getString(i));
break;
}
case BINARY:
{
switch(columnType) {
case Types.BINARY:
case Types.VARBINARY:
byte[] ts = rs.getBytes(i);
if (ts != null) {
builder.set(field, Binary.copy(ts));
}
break;
case Types.BLOB:
Blob blob = rs.getBlob(i);
if (blob != null) {
try {
builder.set(field, Binary.read(blob.getBinaryStream(), (int) blob.length()));
} catch (IOException e) {
throw new UncheckedIOException(e.getMessage(), e);
}
}
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.NCHAR:
case Types.NVARCHAR:
{
String tmp = rs.getString(i);
if (tmp != null) {
builder.set(field, Binary.fromBase64(tmp));
}
break;
}
case Types.NULL:
break;
default:
throw new SQLDataException("Unknown column type " + rs.getMetaData().getColumnTypeName(i) + " for " + descriptor.getType().toString() + " field " + name + " in " + descriptor.getQualifiedName());
}
break;
}
case ENUM:
{
int val = rs.getInt(i);
if (!rs.wasNull()) {
PEnumDescriptor ed = (PEnumDescriptor) field.getDescriptor();
builder.set(field, ed.findById(val));
}
break;
}
case MESSAGE:
{
try {
PMessageDescriptor<?, ?> md = (PMessageDescriptor) field.getDescriptor();
switch(columnType) {
case Types.BINARY:
case Types.VARBINARY:
byte[] data = rs.getBytes(i);
if (data != null) {
ByteArrayInputStream in = new ByteArrayInputStream(data);
builder.set(field, BINARY.deserialize(in, md));
}
break;
case Types.BLOB:
{
Blob blob = rs.getBlob(i);
if (blob != null) {
builder.set(field, BINARY.deserialize(blob.getBinaryStream(), md));
}
break;
}
case Types.CHAR:
case Types.VARCHAR:
case Types.NCHAR:
case Types.NVARCHAR:
{
String tmp = rs.getString(i);
if (tmp != null) {
StringReader reader = new StringReader(tmp);
builder.set(field, JSON.deserialize(reader, md));
}
break;
}
case Types.CLOB:
{
Clob clob = rs.getClob(i);
if (clob != null) {
builder.set(field, JSON.deserialize(clob.getCharacterStream(), md));
}
break;
}
case Types.NULL:
break;
default:
throw new SQLDataException("Unknown column type " + rs.getMetaData().getColumnTypeName(i) + " for " + descriptor.getType().toString() + " field " + name + " in " + descriptor.getQualifiedName());
}
} catch (IOException e) {
throw new UncheckedIOException(e.getMessage(), e);
}
break;
}
case LIST:
case SET:
case MAP:
{
// ... woot?
}
case VOID:
default:
{
throw new SQLDataException("Unhandled column of type " + rs.getMetaData().getColumnTypeName(i) + " for " + descriptor.getType().toString() + " field " + name + " in " + descriptor.getQualifiedName());
}
}
}
}
return builder.build();
}
use of net.morimekta.providence.descriptor.PMessageDescriptor in project providence by morimekta.
the class ProvidenceConfigUtil method getInMessage.
/**
* Look up a key in the message structure. If the key is not found, return
* the default value. Note that the default value will be converted to the
* type of the declared field, not returned verbatim.
*
* @param message The message to look up into.
* @param key The key to look up.
* @param defValue The default value.
* @return The value found or the default.
* @throws ProvidenceConfigException When unable to get value from message.
*/
static Object getInMessage(PMessage message, final String key, Object defValue) throws ProvidenceConfigException {
String sub = key;
String name;
PMessageDescriptor descriptor = message.descriptor();
while (sub.contains(".")) {
int idx = sub.indexOf(".");
name = sub.substring(0, idx);
sub = sub.substring(idx + 1);
PField field = descriptor.findFieldByName(name);
if (field == null) {
throw new ProvidenceConfigException("Message " + descriptor.getQualifiedName() + " has no field named " + name);
}
PDescriptor fieldDesc = field.getDescriptor();
if (fieldDesc.getType() != PType.MESSAGE) {
throw new ProvidenceConfigException("Field '" + name + "' is not of message type in " + descriptor.getQualifiedName());
}
descriptor = (PMessageDescriptor) fieldDesc;
if (message != null) {
message = (PMessage) message.get(field.getId());
}
}
PField field = descriptor.findFieldByName(sub);
if (field == null) {
throw new ProvidenceConfigException("Message " + descriptor.getQualifiedName() + " has no field named " + sub);
}
if (message == null || !message.has(field.getId())) {
return asType(field.getDescriptor(), defValue);
}
return message.get(field.getId());
}
use of net.morimekta.providence.descriptor.PMessageDescriptor in project providence by morimekta.
the class ProvidenceConfigParser method parseDefinitionValue.
@SuppressWarnings("unchecked")
Object parseDefinitionValue(ProvidenceConfigContext context, Tokenizer tokenizer) throws IOException {
Token token = tokenizer.expect("Start of def value");
if (token.isReal()) {
return Double.parseDouble(token.asString());
} else if (token.isInteger()) {
return Long.parseLong(token.asString());
} else if (token.isStringLiteral()) {
return token.decodeLiteral(strict);
} else if (TRUE.equalsIgnoreCase(token.asString())) {
return Boolean.TRUE;
} else if (FALSE.equalsIgnoreCase(token.asString())) {
return Boolean.FALSE;
} else if (Token.B64.equals(token.asString())) {
tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
return Binary.fromBase64(tokenizer.readBinary(Token.kParamsEnd));
} else if (Token.HEX.equals(token.asString())) {
tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
return Binary.fromHexString(tokenizer.readBinary(Token.kParamsEnd));
} else if (token.isDoubleQualifiedIdentifier()) {
// this may be an enum reference, must be
// - package.EnumType.IDENTIFIER
String id = token.asString();
int l = id.lastIndexOf(Token.kIdentifierSep);
try {
PEnumDescriptor ed = registry.getEnumType(id.substring(0, l));
PEnumValue val = ed.findByName(id.substring(l + 1));
if (val == null && strict) {
throw new TokenizerException(token, "Unknown %s value: %s", id.substring(0, l), id.substring(l + 1)).setLine(tokenizer.getLine());
}
// Note that unknown enum value results in null. Therefore we don't catch null values here.
return val;
} catch (IllegalArgumentException e) {
// No such declared type.
if (strict) {
throw new TokenizerException(token, "Unknown enum identifier: %s", id.substring(0, l)).setLine(tokenizer.getLine());
}
consumeValue(context, tokenizer, token);
} catch (ClassCastException e) {
// Not an enum.
throw new TokenizerException(token, "Identifier " + id + " does not reference an enum, from " + token.asString()).setLine(tokenizer.getLine());
}
} else if (token.isQualifiedIdentifier()) {
// Message type.
PMessageDescriptor descriptor;
try {
descriptor = registry.getMessageType(token.asString());
} catch (IllegalArgumentException e) {
// - strict mode: all types must be known.
if (strict) {
throw new TokenizerException(token, "Unknown declared type: %s", token.asString()).setLine(tokenizer.getLine());
}
consumeValue(context, tokenizer, token);
return null;
}
PMessageBuilder builder = descriptor.builder();
if (tokenizer.expectSymbol("message start or inherits", '{', ':') == ':') {
token = tokenizer.expect("inherits reference");
PMessage inheritsFrom = resolve(context, token, tokenizer, descriptor);
if (inheritsFrom == null) {
throw new TokenizerException(token, "Inheriting from null reference: %s", token.asString()).setLine(tokenizer.getLine());
}
builder.merge(inheritsFrom);
tokenizer.expectSymbol("message start", '{');
}
return parseMessage(tokenizer, context, builder);
} else {
throw new TokenizerException(token, "Invalid define value " + token.asString()).setLine(tokenizer.getLine());
}
return null;
}
Aggregations