Search in sources :

Example 1 with JsonException

use of net.morimekta.util.json.JsonException in project providence by morimekta.

the class JsonSerializer method parseMapKey.

private Object parseMapKey(String key, PDescriptor keyType) throws SerializerException {
    try {
        switch(keyType.getType()) {
            case BOOL:
                if (key.equalsIgnoreCase("true")) {
                    return Boolean.TRUE;
                } else if (key.equalsIgnoreCase("false")) {
                    return Boolean.FALSE;
                }
                throw new SerializerException("Invalid boolean value: \"" + Strings.escape(key) + "\"");
            case BYTE:
                return Byte.parseByte(key);
            case I16:
                return Short.parseShort(key);
            case I32:
                return Integer.parseInt(key);
            case I64:
                return Long.parseLong(key);
            case DOUBLE:
                try {
                    JsonTokenizer tokenizer = new JsonTokenizer(new ByteArrayInputStream(key.getBytes(StandardCharsets.US_ASCII)));
                    JsonToken token = tokenizer.next();
                    if (!token.isNumber()) {
                        throw new SerializerException("Unable to parse double from key \"" + key + "\"");
                    } else if (tokenizer.hasNext()) {
                        throw new SerializerException("Garbage after double: \"" + key + "\"");
                    }
                    return token.doubleValue();
                } catch (SerializerException e) {
                    throw e;
                } catch (JsonException | IOException e) {
                    throw new SerializerException(e, "Unable to parse double from key \"" + key + "\"");
                }
            case STRING:
                return key;
            case BINARY:
                try {
                    return Binary.fromBase64(key);
                } catch (IllegalArgumentException e) {
                    throw new SerializerException(e, "Unable to parse Base64 data");
                }
            case ENUM:
                PEnumBuilder<?> eb = ((PEnumDescriptor<?>) keyType).builder();
                if (Strings.isInteger(key)) {
                    eb.setById(Integer.parseInt(key));
                } else {
                    eb.setByName(key);
                }
                if (readStrict && !eb.valid()) {
                    throw new SerializerException("\"%s\" is not a known enum value for %s", Strings.escape(key), keyType.getQualifiedName());
                }
                return eb.build();
            case MESSAGE:
                PMessageDescriptor<?, ?> st = (PMessageDescriptor<?, ?>) keyType;
                if (!st.isSimple()) {
                    throw new SerializerException("Only simple structs can be used as map key. %s is not.", st.getQualifiedName());
                }
                ByteArrayInputStream input = new ByteArrayInputStream(key.getBytes(StandardCharsets.UTF_8));
                try {
                    JsonTokenizer tokenizer = new JsonTokenizer(input);
                    if (JsonToken.kMapStart == tokenizer.expectSymbol("message start", JsonToken.kMapStart, JsonToken.kListStart)) {
                        return parseMessage(tokenizer, st);
                    } else {
                        return parseCompactMessage(tokenizer, st);
                    }
                } catch (JsonException | IOException e) {
                    throw new SerializerException(e, "Error parsing message key: " + e.getMessage());
                }
            default:
                throw new SerializerException("Illegal key type: %s", keyType.getType());
        }
    } catch (NumberFormatException nfe) {
        throw new SerializerException(nfe, "Unable to parse numeric value %s", key);
    }
}
Also used : JsonException(net.morimekta.util.json.JsonException) IOException(java.io.IOException) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor) ByteArrayInputStream(java.io.ByteArrayInputStream) JsonToken(net.morimekta.util.json.JsonToken) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) JsonTokenizer(net.morimekta.util.json.JsonTokenizer)

Example 2 with JsonException

use of net.morimekta.util.json.JsonException in project providence by morimekta.

the class JsonSerializer method parseServiceCall.

@SuppressWarnings("unchecked")
private <T extends PMessage<T, F>, F extends PField> PServiceCall<T, F> parseServiceCall(JsonTokenizer tokenizer, PService service) throws IOException {
    PServiceCallType type = null;
    String methodName = null;
    int sequence = 0;
    try {
        tokenizer.expectSymbol("service call start", JsonToken.kListStart);
        methodName = tokenizer.expectString("method name").rawJsonLiteral();
        tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
        JsonToken callTypeToken = tokenizer.expect("call type");
        if (callTypeToken.isInteger()) {
            int typeKey = callTypeToken.byteValue();
            type = PServiceCallType.findById(typeKey);
            if (type == null) {
                throw new SerializerException("Service call type " + typeKey + " is not valid").setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
            }
        } else if (callTypeToken.isLiteral()) {
            String typeName = callTypeToken.rawJsonLiteral();
            type = PServiceCallType.findByName(typeName.toUpperCase(Locale.US));
            if (type == null) {
                throw new SerializerException("Service call type \"" + Strings.escape(typeName) + "\" is not valid").setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
            }
        } else {
            throw new SerializerException("Invalid service call type token " + callTypeToken.asString()).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
        }
        tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
        sequence = tokenizer.expectNumber("Service call sequence").intValue();
        tokenizer.expectSymbol("entry sep", JsonToken.kListSep);
        if (type == PServiceCallType.EXCEPTION) {
            PApplicationException ex = (PApplicationException) parseTypedValue(tokenizer.expect("Message start"), tokenizer, PApplicationException.kDescriptor, false);
            tokenizer.expectSymbol("service call end", JsonToken.kListEnd);
            return (PServiceCall<T, F>) new PServiceCall<>(methodName, type, sequence, ex);
        }
        PServiceMethod method = service.getMethod(methodName);
        if (method == null) {
            throw new SerializerException("No such method " + methodName + " on " + service.getQualifiedName()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
        }
        @SuppressWarnings("unchecked") PMessageDescriptor<T, F> descriptor = isRequestCallType(type) ? method.getRequestType() : method.getResponseType();
        if (descriptor == null) {
            throw new SerializerException("No %s type for %s.%s()", isRequestCallType(type) ? "request" : "response", service.getQualifiedName(), methodName).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
        }
        T message = (T) parseTypedValue(tokenizer.expect("message start"), tokenizer, descriptor, false);
        tokenizer.expectSymbol("service call end", JsonToken.kListEnd);
        return new PServiceCall<>(methodName, type, sequence, message);
    } catch (SerializerException se) {
        throw new SerializerException(se).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
    } catch (JsonException je) {
        throw new JsonSerializerException(je).setMethodName(methodName).setCallType(type).setSequenceNo(sequence);
    }
}
Also used : JsonException(net.morimekta.util.json.JsonException) PServiceCallType(net.morimekta.providence.PServiceCallType) PApplicationException(net.morimekta.providence.PApplicationException) PServiceCall(net.morimekta.providence.PServiceCall) JsonToken(net.morimekta.util.json.JsonToken) PServiceMethod(net.morimekta.providence.descriptor.PServiceMethod)

Example 3 with JsonException

use of net.morimekta.util.json.JsonException in project providence by morimekta.

the class JsonSerializerExceptionTest method testException.

@Test
public void testException() {
    JsonException cause = new JsonException("foo", "bar bar bar", 1, 5, 3);
    JsonSerializerException ex = new JsonSerializerException(cause);
    ex.setMethodName("bar");
    ex.setSequenceNo(42);
    ex.setCallType(PServiceCallType.CALL);
    assertThat(ex.getMessage(), is("foo"));
    assertThat(ex.getLine(), is("bar bar bar"));
    assertThat(ex.getLineNo(), is(1));
    assertThat(ex.getLinePos(), is(5));
    assertThat(ex.getCause(), is(sameInstance(cause)));
    assertThat(ex.getLen(), is(3));
    assertThat(ex.asString(), is("JSON Error in bar on line 1: foo\n" + "bar bar bar\n" + "----^^^"));
    assertThat(ex.toString(), is("JsonSerializerException{foo, line=1, pos=5, method=bar, type=CALL, seq=42}"));
    cause = new JsonException("foo", null, 0, 0, 0);
    ex = new JsonSerializerException(cause);
    ex.setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
    assertThat(ex.getMessage(), is("foo"));
    assertThat(ex.getLine(), is(nullValue()));
    assertThat(ex.getCause(), is(sameInstance(cause)));
    assertThat(ex.asString(), is("JSON Error: foo"));
    assertThat(ex.toString(), is("JsonSerializerException{foo, e=INVALID_MESSAGE_TYPE}"));
    try {
        ex.initCause(new IOException());
        fail();
    } catch (UnsupportedOperationException e) {
    }
}
Also used : JsonException(net.morimekta.util.json.JsonException) IOException(java.io.IOException) Test(org.junit.Test)

Aggregations

JsonException (net.morimekta.util.json.JsonException)3 IOException (java.io.IOException)2 JsonToken (net.morimekta.util.json.JsonToken)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 PApplicationException (net.morimekta.providence.PApplicationException)1 PServiceCall (net.morimekta.providence.PServiceCall)1 PServiceCallType (net.morimekta.providence.PServiceCallType)1 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)1 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)1 PServiceMethod (net.morimekta.providence.descriptor.PServiceMethod)1 JsonTokenizer (net.morimekta.util.json.JsonTokenizer)1 Test (org.junit.Test)1