Search in sources :

Example 6 with PEnumValue

use of net.morimekta.providence.PEnumValue in project providence by morimekta.

the class LogFormatter method appendPrimitive.

private void appendPrimitive(IndentedPrintWriter writer, Object o) {
    if (o instanceof PEnumValue) {
        writer.print(((PEnumValue) o).asString());
    } else if (o instanceof CharSequence) {
        writer.print(Token.kLiteralDoubleQuote);
        writer.print(Strings.escape((CharSequence) o));
        writer.print(Token.kLiteralDoubleQuote);
    } else if (o instanceof Binary) {
        Binary b = (Binary) o;
        writer.append(Token.B64).append(Token.kParamsStart).append(b.toBase64()).append(Token.kParamsEnd);
    } else if (o instanceof Boolean) {
        writer.print(((Boolean) o).booleanValue());
    } else if (o instanceof Byte || o instanceof Short || o instanceof Integer || o instanceof Long) {
        writer.print(o.toString());
    } else if (o instanceof Double) {
        Double d = (Double) o;
        if (d.equals(((double) d.longValue()))) {
            // actually an integer or long value.
            writer.print(d.longValue());
        } else {
            writer.print(d.doubleValue());
        }
    } else {
        throw new IllegalArgumentException("Unknown primitive type class " + o.getClass().getSimpleName());
    }
}
Also used : PEnumValue(net.morimekta.providence.PEnumValue) Binary(net.morimekta.util.Binary)

Example 7 with PEnumValue

use of net.morimekta.providence.PEnumValue in project providence by morimekta.

the class TProtocolSerializerTest method assertConsistent.

@SuppressWarnings("unchecked")
public <Providence extends PMessage<Providence, ProvidenceField>, ProvidenceField extends PField, Thrift extends TBase<Thrift, ThriftField>, ThriftField extends TFieldIdEnum> void assertConsistent(String prefix, Providence providence, Thrift thrift) {
    if (providence.descriptor().getVariant() == PMessageVariant.UNION) {
        TUnion<?, ThriftField> t_union = (TUnion) thrift;
        PUnion<?, ProvidenceField> p_union = (PUnion) providence;
        ThriftField t_field = t_union.getSetField();
        PField p_field = p_union.unionField();
        assertEquals(p_field.getId(), t_field.getThriftFieldId());
    } else {
        for (PField field : providence.descriptor().getFields()) {
            ThriftField thriftField = thrift.fieldForId(field.getId());
            String fieldPath = (prefix.isEmpty() ? "" : prefix + ".") + field.getName();
            assertEquals("has " + fieldPath, providence.has(field.getId()), thrift.isSet(thriftField));
            if (providence.has(field.getId())) {
                switch(field.getType()) {
                    case MESSAGE:
                        assertConsistent(fieldPath, (PMessage) providence.get(field.getId()), (TBase) thrift.getFieldValue(thriftField));
                        break;
                    case ENUM:
                        {
                            PEnumValue<?> pe = providence.get(field.getId());
                            TEnum te = (TEnum) thrift.getFieldValue(thriftField);
                            assertEquals(fieldPath, pe.asInteger(), te.getValue());
                            break;
                        }
                    case BINARY:
                        {
                            Binary pBin = providence.get(field.getId());
                            byte[] tBytes = (byte[]) thrift.getFieldValue(thriftField);
                            Binary tBin = Binary.wrap(tBytes);
                            assertEquals(fieldPath, pBin, tBin);
                            break;
                        }
                    case MAP:
                        {
                            Map pm = providence.get(field.getId());
                            Map tm = (Map) thrift.getFieldValue(thriftField);
                            assertEquals(fieldPath + " size", pm.size(), tm.size());
                            // TODO: Compare actual content.
                            break;
                        }
                    case SET:
                        {
                            Set ps = providence.get(field.getId());
                            Set ts = (Set) thrift.getFieldValue(thriftField);
                            assertEquals(fieldPath + " size", ps.size(), ts.size());
                            // TODO: Compare actual content.
                            break;
                        }
                    case LIST:
                        {
                            List pl = providence.get(field.getId());
                            List tl = (List) thrift.getFieldValue(thriftField);
                            assertEquals(fieldPath + " size", pl.size(), tl.size());
                            for (int i = 0; i < pl.size(); ++i) {
                                String itemPath = fieldPath + "[" + i + "]";
                                Object pi = pl.get(i);
                                Object ti = tl.get(i);
                                if (pi instanceof PMessage) {
                                    assertConsistent(itemPath, (PMessage) pi, (TBase) ti);
                                } else if (pi instanceof Set) {
                                // TODO: Compare actual content.
                                } else if (pi instanceof List) {
                                // TODO: Compare actual content.
                                } else if (pi instanceof Map) {
                                // TODO: Compare actual content.
                                } else if (pi instanceof Binary) {
                                    Binary pb = (Binary) pi;
                                    Binary tb = Binary.wrap(((ByteBuffer) ti).array());
                                    assertEquals(itemPath, pb, tb);
                                } else if (pi instanceof PEnumValue) {
                                    PEnumValue pe = (PEnumValue) pi;
                                    TEnum te = (TEnum) ti;
                                    assertEquals(itemPath, pe.asInteger(), te.getValue());
                                } else {
                                    assertEquals(itemPath, pi, ti);
                                }
                            }
                            break;
                        }
                    default:
                        assertEquals(fieldPath, providence.get(field.getId()), thrift.getFieldValue(thriftField));
                        break;
                }
            }
        }
    }
}
Also used : TUnion(org.apache.thrift.TUnion) Set(java.util.Set) PField(net.morimekta.providence.descriptor.PField) PEnumValue(net.morimekta.providence.PEnumValue) ByteBuffer(java.nio.ByteBuffer) TEnum(org.apache.thrift.TEnum) PMessage(net.morimekta.providence.PMessage) PUnion(net.morimekta.providence.PUnion) ArrayList(java.util.ArrayList) List(java.util.List) TBase(org.apache.thrift.TBase) Binary(net.morimekta.util.Binary) Map(java.util.Map)

Example 8 with PEnumValue

use of net.morimekta.providence.PEnumValue in project providence by morimekta.

the class MessageFieldArgument method apply.

@Override
@SuppressWarnings("unchecked")
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
    if (message.has(field)) {
        switch(field.getType()) {
            case BOOL:
                {
                    boolean value = message.get(field);
                    if (type == Types.BOOLEAN || type == Types.BIT) {
                        statement.setBoolean(position, value);
                    } else {
                        statement.setInt(position, value ? 1 : 0);
                    }
                    break;
                }
            case BYTE:
                {
                    statement.setByte(position, message.get(field));
                    break;
                }
            case I16:
                {
                    statement.setShort(position, message.get(field));
                    break;
                }
            case I32:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(1000L * (int) message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setInt(position, message.get(field));
                    }
                    break;
                }
            case I64:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setLong(position, message.get(field));
                    }
                    break;
                }
            case DOUBLE:
                {
                    statement.setDouble(position, message.get(field));
                    break;
                }
            case STRING:
                {
                    statement.setString(position, message.get(field));
                    break;
                }
            case BINARY:
                {
                    Binary binary = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                statement.setBytes(position, binary.get());
                                break;
                            }
                        case Types.BLOB:
                            {
                                statement.setBlob(position, binary.getInputStream());
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                statement.setString(position, binary.toBase64());
                                break;
                            }
                        default:
                            throw new ResultSetException("Unknown binary field type: " + type + " for " + field, null, ctx);
                    }
                    break;
                }
            case ENUM:
                {
                    PEnumValue value = message.get(field);
                    statement.setInt(position, value.asInteger());
                    break;
                }
            case MESSAGE:
                {
                    PMessage value = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBytes(position, out.toByteArray());
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.BLOB:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBlob(position, new ByteArrayInputStream(out.toByteArray()));
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setString(position, writer.getBuffer().toString());
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        case Types.CLOB:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setClob(position, new StringReader(writer.getBuffer().toString()));
                                } catch (IOException e) {
                                    throw new ResultSetException(e.getMessage(), e, ctx);
                                }
                                break;
                            }
                        default:
                            throw new ResultSetException("Unknown message field type: " + type + " for " + field, null, ctx);
                    }
                    break;
                }
            default:
                throw new ResultSetException("Unhandled field type in SQL: " + field, null, ctx);
        }
    } else {
        statement.setNull(position, type);
    }
}
Also used : ResultSetException(org.jdbi.v3.core.result.ResultSetException) StringWriter(java.io.StringWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) PMessage(net.morimekta.providence.PMessage) StringReader(java.io.StringReader) PEnumValue(net.morimekta.providence.PEnumValue) Binary(net.morimekta.util.Binary) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Timestamp(java.sql.Timestamp) PrintWriter(java.io.PrintWriter)

Example 9 with PEnumValue

use of net.morimekta.providence.PEnumValue 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;
}
Also used : PMessageBuilder(net.morimekta.providence.PMessageBuilder) PMessage(net.morimekta.providence.PMessage) PEnumValue(net.morimekta.providence.PEnumValue) Token(net.morimekta.providence.serializer.pretty.Token) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor)

Example 10 with PEnumValue

use of net.morimekta.providence.PEnumValue in project providence by morimekta.

the class GenericMethods method assertValueIntegrity.

@SuppressWarnings("unchecked")
private void assertValueIntegrity(PField expectedField, Object actualValue, Object expectedValue) {
    if (actualValue == null || expectedValue == null) {
        assertThat(expectedField.toString(), actualValue, is(expectedValue));
    } else if (actualValue instanceof PMessage && expectedValue instanceof PMessage) {
        assertFieldIntegrity((PMessage<?, ?>) actualValue, (PMessage<?, ?>) expectedValue);
    } else if (actualValue instanceof PEnumValue && expectedValue instanceof PEnumValue) {
        assertThat(expectedField.toString(), ((PEnumValue) actualValue).getId(), is(((PEnumValue) expectedValue).getId()));
    } else if (actualValue instanceof List && expectedValue instanceof List) {
        List<Object> actualList = (List) actualValue;
        List<Object> expectedList = (List) expectedValue;
        assertThat(expectedField.toString(), actualList, hasSize(expectedList.size()));
        for (int i = 0; i < actualList.size(); ++i) {
            assertValueIntegrity(expectedField, actualList.get(i), expectedList.get(i));
        }
    } else if (actualValue instanceof Set && expectedValue instanceof Set) {
        TreeSet<Object> actualSet = new TreeSet<>((Set<Object>) actualValue);
        TreeSet<Object> expectedSet = new TreeSet<>((Set<Object>) expectedValue);
        assertThat(expectedField.toString(), actualSet, hasSize(expectedSet.size()));
        while (actualSet.size() > 0) {
            assertValueIntegrity(expectedField, actualSet.pollFirst(), expectedSet.pollFirst());
        }
    } else if (actualValue instanceof Map && expectedValue instanceof Map) {
        Map actualMap = (Map) actualValue;
        Map expectedMap = (Map) expectedValue;
        assertValueIntegrity(expectedField, actualMap.keySet(), expectedMap.keySet());
        for (Object key : actualMap.keySet()) {
            if (key instanceof PEnumValue) {
                // Search for the enum with the same ID in the expected map keys.
                Object expectedKey = expectedMap.keySet().stream().filter(k -> ((PEnumValue) k).getId() == ((PEnumValue) key).getId()).findFirst().orElse(null);
                if (expectedKey == null) {
                    throw new AssertionError("No expected map key matching " + key);
                }
                assertValueIntegrity(expectedField, actualMap.get(key), expectedMap.get(expectedKey));
            } else if (key instanceof PMessage) {
                // The messages should sort identically.
                TreeSet<PMessage> actualKeys = new TreeSet<>(actualMap.keySet());
                TreeSet<PMessage> expectedKeys = new TreeSet<>(expectedMap.keySet());
                while (expectedKeys.size() > 0) {
                    PMessage actual = actualKeys.pollFirst();
                    PMessage expected = expectedKeys.pollFirst();
                    assertFieldIntegrity(actual, expected);
                    assertValueIntegrity(expectedField, actualMap.get(actual), expectedMap.get(expected));
                }
            } else {
                assertValueIntegrity(expectedField, actualMap.get(key), expectedMap.get(key));
            }
        }
    } else {
        assertThat(expectedField.toString(), actualValue, is(expectedValue));
    }
}
Also used : Config(com.hazelcast.config.Config) HazelcastInstance(com.hazelcast.core.HazelcastInstance) AfterClass(org.junit.AfterClass) GeneratorWatcher(net.morimekta.providence.testing.generator.GeneratorWatcher) Set(java.util.Set) Random(java.util.Random) TreeSet(java.util.TreeSet) PMessage(net.morimekta.providence.PMessage) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) Assert.assertThat(org.junit.Assert.assertThat) PField(net.morimekta.providence.descriptor.PField) List(java.util.List) IMap(com.hazelcast.core.IMap) Rule(org.junit.Rule) SimpleGeneratorWatcher(net.morimekta.providence.testing.generator.SimpleGeneratorWatcher) Map(java.util.Map) PEnumValue(net.morimekta.providence.PEnumValue) Is.is(org.hamcrest.core.Is.is) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) ProvidenceMatchers.equalToMessage(net.morimekta.providence.testing.ProvidenceMatchers.equalToMessage) Matchers.hasSize(org.hamcrest.Matchers.hasSize) PMessageBuilder(net.morimekta.providence.PMessageBuilder) Fairy(io.codearte.jfairy.Fairy) Before(org.junit.Before) Set(java.util.Set) TreeSet(java.util.TreeSet) PMessage(net.morimekta.providence.PMessage) TreeSet(java.util.TreeSet) PEnumValue(net.morimekta.providence.PEnumValue) List(java.util.List) IMap(com.hazelcast.core.IMap) Map(java.util.Map)

Aggregations

PEnumValue (net.morimekta.providence.PEnumValue)11 PMessage (net.morimekta.providence.PMessage)6 Binary (net.morimekta.util.Binary)6 Map (java.util.Map)5 List (java.util.List)3 Set (java.util.Set)3 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)3 PMap (net.morimekta.providence.descriptor.PMap)3 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 PrintWriter (java.io.PrintWriter)2 StringReader (java.io.StringReader)2 StringWriter (java.io.StringWriter)2 Timestamp (java.sql.Timestamp)2 PMessageBuilder (net.morimekta.providence.PMessageBuilder)2 PField (net.morimekta.providence.descriptor.PField)2 PList (net.morimekta.providence.descriptor.PList)2 PSet (net.morimekta.providence.descriptor.PSet)2