@ExceptionHandler({HttpMessageNotReadableException.class, InvalidJsonException.class, InvalidFormatException.class}) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public ResponseError handleInputNotReadableException(Exception exception) { final Throwable cause = exception.getCause() == null ? exception : exception.getCause(); if (cause instanceof UnrecognizedPropertyException) { return constructError("error.invalid_json_key", ((UnrecognizedPropertyException) cause).getPropertyName()); } else if (cause instanceof InvalidTypeIdException || (cause instanceof JsonMappingException && cause.getMessage() .contains("missing property 'type'"))) { return constructError("error.invalid_type_with_set_prompt"); } else if (cause instanceof InvalidFormatException) { for (InvalidFormatException.Reference reference : ((InvalidFormatException) cause) .getPath()) { if ("operations".equals(reference.getFieldName())) { return constructError("error.permission.invalid_operation"); } } } return badRequestResponse(); }
@Override protected MethodSpec implementDeserializeMethod(TypeElement typeElement, Builder deserializeMethodBuilder) { Optional<DeserializationConstructs> constructs = loadConstructs(typeElement); if (!constructs.isPresent()) { return deserializeMethodBuilder.addStatement("return null").build(); } TypeElement enumTypeElement = constructs.get().getEnumTypeElement(); ImmutableList<Element> enumValueElements = constructs.get().getEnumValueElements(); ExecutableElement enumValueAccessorMethod = constructs.get().getEnumValueAccessorMethod(); ExecutableElement enumInstanceAccessorMethod = constructs.get().getEnumInstanceAccessorMethod(); String memberVariableName = this.processorUtil.createMemberVariableName(enumValueAccessorMethod); deserializeMethodBuilder.addStatement("$T codec = $L.getCodec()", ObjectCodec.class, JSON_PARSER_PARAMETER_NAME) .addStatement("$T rootNode = codec.readTree($L)", JsonNode.class, JSON_PARSER_PARAMETER_NAME) .addStatement("$T typeNode = rootNode.get($S)", JsonNode.class, memberVariableName) .beginControlFlow("if (typeNode == null)") .addStatement("$T javaType = $L.constructType($T.class)", JavaType.class, DESERIALIZATION_CONTEXT_PARAMETER_NAME, enumTypeElement) .addStatement("throw new $T($L, \"$L not present\", javaType, null)", InvalidTypeIdException.class, JSON_PARSER_PARAMETER_NAME, memberVariableName) .endControlFlow() .addStatement("$T type = codec.treeToValue(typeNode, $T.$L)", enumTypeElement, enumTypeElement, "class") .beginControlFlow("switch (type)"); enumValueElements.forEach(enumValueElement -> deserializeMethodBuilder .beginControlFlow("case $L:", enumValueElement) .addStatement("return codec.treeToValue(rootNode, $T.$L.$L)", enumTypeElement, enumValueElement, enumInstanceAccessorMethod) .endControlFlow()); return deserializeMethodBuilder.beginControlFlow("default :") .addStatement("return null") .endControlFlow() .endControlFlow() .build(); }
@Override public JavaType typeFromId(DatabindContext context, String id) throws IOException { Class<?> subType; id = id.toLowerCase(); switch (id) { case CertificateCredentialVersionData.CREDENTIAL_TYPE: subType = CertificateSetRequest.class; break; case ValueCredentialVersionData.CREDENTIAL_TYPE: subType = ValueSetRequest.class; break; case JsonCredentialVersionData.CREDENTIAL_TYPE: subType = JsonSetRequest.class; break; case PasswordCredentialVersionData.CREDENTIAL_TYPE: subType = PasswordSetRequest.class; break; case RsaCredentialVersionData.CREDENTIAL_TYPE: subType = RsaSetRequest.class; break; case SshCredentialVersionData.CREDENTIAL_TYPE: subType = SshSetRequest.class; break; case UserCredentialVersionData.CREDENTIAL_TYPE: subType = UserSetRequest.class; break; default: String message = String.format("Could not resolve type id '%s' into a subtype of %s", id, baseType); throw new InvalidTypeIdException(null, message, baseType, id); } return context.constructSpecializedType(baseType, subType); }
@Test(expected = InvalidTypeIdException.class) public void whenTypeIsEmptyString_throwsException() throws IOException { String json = "{" + "\"name\":\"some-name\"," + "\"type\":\"\"," + "\"value\":\"some-value\"," + "\"overwrite\":true" + "}"; JsonTestHelper.deserializeChecked(json, BaseCredentialSetRequest.class); }
@Test(expected = InvalidTypeIdException.class) public void whenTypeIsUnknown_throwsException() throws IOException { String json = "{" + "\"name\":\"some-name\"," + "\"type\":\"moose\"," + "\"value\":\"some-value\"," + "\"overwrite\":true" + "}"; JsonTestHelper.deserializeChecked(json, BaseCredentialSetRequest.class); }