/** * Executes the given Function. An occurring {@link JsonRuntimeException}, * {@code IllegalArgumentException} or {@code NullPointerException} is caught, wrapped and re-thrown as * {@code DittoJsonException}. * * @param function to function which potentially throws a {@code JsonRuntimeException}. * @param input the input to the function. * @param <I> the type of the input to the function. * @param <T> the type of results the function returns. * @return the results of the function. * @throws DittoJsonException if a {@code JsonRuntimeException} occurred. */ public static <I, T> T wrapJsonRuntimeException(final Function<I, T> function, final I input) { try { return function.apply(input); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException e) { throw new DittoJsonException(e); } // "ditto-json" library also throws IllegalArgumentException when for example strings which may not be empty // (e.g. keys) are empty // "ditto-json" library also throws NullPointerException when for example non-nullable objects are null }
/** * Executes the given Supplier. An occurring {@link JsonRuntimeException}, {@code IllegalArgumentException}, * {@code UnsupportedOperationException}, or {@code NullPointerException} is caught, wrapped and re-thrown as * {@code DittoJsonException}. * * @param supplier the supplier which potentially throws a {@code JsonRuntimeException}. * @param <T> the type of results the supplier returns. * @return the results of the supplier. * @throws DittoJsonException if a {@code JsonRuntimeException} occurred. */ public static <T> T wrapJsonRuntimeException(final Supplier<T> supplier) { try { return supplier.get(); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException | UnsupportedOperationException e) { throw new DittoJsonException(e); } // "ditto-json" library also throws IllegalArgumentException when for example strings which may not be empty // (e.g. keys) are empty // "ditto-json" library also throws NullPointerException when for example non-nullable objects are null }
@Override public ThingSearchCommand parse(final JsonObject jsonObject, final DittoHeaders dittoHeaders) { try { return super.parse(jsonObject, dittoHeaders); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException | ClassCastException e) { throw new DittoJsonException(e, dittoHeaders); } } }
@Override public ThingSearchCommand parse(final JsonObject jsonObject, final DittoHeaders dittoHeaders) { try { return super.parse(jsonObject, dittoHeaders); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException | ClassCastException e) { throw new DittoJsonException(e, dittoHeaders); } } }
@Override public ThingSearchSudoCommand parse(final JsonObject jsonObject, final DittoHeaders dittoHeaders) { try { return super.parse(jsonObject, dittoHeaders); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException | ClassCastException e) { throw new DittoJsonException(e, dittoHeaders); } } }
@Override public ThingSearchSudoCommand parse(final JsonObject jsonObject, final DittoHeaders dittoHeaders) { try { return super.parse(jsonObject, dittoHeaders); } catch (final JsonRuntimeException | IllegalArgumentException | NullPointerException | ClassCastException e) { throw new DittoJsonException(e, dittoHeaders); } } }
private void validateCommandResponseType() { final String actualCommandResponseType = jsonObject.getValueOrThrow(CommandResponse.JsonFields.TYPE); if (!expectedCommandResponseType.equals(actualCommandResponseType)) { final String msgPattern = "Command Response JSON was not a <{0}> command response but a <{1}>!"; final String msg = MessageFormat.format(msgPattern, expectedCommandResponseType, actualCommandResponseType); throw new DittoJsonException(new JsonParseException(msg)); } }
private void validateCommandResponseType() { final String actualCommandResponseType = jsonObject.getValueOrThrow(CommandResponse.JsonFields.TYPE); if (!expectedCommandResponseType.equals(actualCommandResponseType)) { final String msgPattern = "Command Response JSON was not a <{0}> command response but a <{1}>!"; final String msg = MessageFormat.format(msgPattern, expectedCommandResponseType, actualCommandResponseType); throw new DittoJsonException(new JsonParseException(msg)); } }
private void validateCommandType() { final JsonFieldDefinition<String> typeFieldDefinition = Command.JsonFields.TYPE; final Optional<String> actualCommandTypeOptional = jsonObject.getValue(typeFieldDefinition); final String actualCommandType = actualCommandTypeOptional.orElseGet(() -> { // "type" was introduced in V2, if not present, take "command" instead. final String commandTypePrefix = expectedCommandType.split(":")[0]; return jsonObject.getValue(Command.JsonFields.ID) .map(id -> commandTypePrefix + ':' + id) .orElseThrow(() -> new JsonMissingFieldException(typeFieldDefinition)); }); if (!expectedCommandType.equals(actualCommandType)) { final String msgPattern = "Command JSON was not a <{0}> command but a <{1}>!"; final String msg = MessageFormat.format(msgPattern, expectedCommandType, actualCommandType); throw new DittoJsonException(new JsonParseException(msg)); } }
private static String[] splitTypeWithPath(final String typeWithPath) { final String[] split = typeWithPath.split(ResourceKey.KEY_DELIMITER, 2); if (split.length < 2) { throw new DittoJsonException(JsonParseException.newBuilder() .message("The provided string was not in the expected format 'type:path'") .build()); } return split; }
private void validateCommandType() { final JsonFieldDefinition<String> typeFieldDefinition = Command.JsonFields.TYPE; final Optional<String> actualCommandTypeOptional = jsonObject.getValue(typeFieldDefinition); final String actualCommandType = actualCommandTypeOptional.orElseGet(() -> { // "type" was introduced in V2, if not present, take "command" instead. final String commandTypePrefix = expectedCommandType.split(":")[0]; return jsonObject.getValue(Command.JsonFields.ID) .map(id -> commandTypePrefix + ':' + id) .orElseThrow(() -> new JsonMissingFieldException(typeFieldDefinition)); }); if (!expectedCommandType.equals(actualCommandType)) { final String msgPattern = "Command JSON was not a <{0}> command but a <{1}>!"; final String msg = MessageFormat.format(msgPattern, expectedCommandType, actualCommandType); throw new DittoJsonException(new JsonParseException(msg)); } }
private static JsonObject getPayload(final JsonObject sourceJsonObject) { final JsonObject result; final Optional<JsonValue> payloadJsonOptional = sourceJsonObject.getValue(JSON_PAYLOAD); if (payloadJsonOptional.isPresent()) { final JsonValue payloadJson = payloadJsonOptional.get(); if (!payloadJson.isObject()) { final String msgPattern = "Value <{0}> for <{1}> was not of type <{2}>!"; final String simpleName = JSON_PAYLOAD.getValueType().getSimpleName(); final String msg = MessageFormat.format(msgPattern, payloadJson, JSON_PAYLOAD.getPointer(), simpleName); throw new DittoJsonException(new IllegalArgumentException(msg)); } else { result = payloadJson.asObject(); } } else { result = JsonFactory.newObject(); } return result; }
private static JsonObject getPayload(final JsonObject sourceJsonObject) { final JsonObject result; final Optional<JsonValue> payloadJsonOptional = sourceJsonObject.getValue(JSON_PAYLOAD); if (payloadJsonOptional.isPresent()) { final JsonValue payloadJson = payloadJsonOptional.get(); if (!payloadJson.isObject()) { final String msgPattern = "Value <{0}> for <{1}> was not of type <{2}>!"; final String simpleName = JSON_PAYLOAD.getValueType().getSimpleName(); final String msg = MessageFormat.format(msgPattern, payloadJson, JSON_PAYLOAD.getPointer(), simpleName); throw new DittoJsonException(new IllegalArgumentException(msg)); } else { result = payloadJson.asObject(); } } else { result = JsonFactory.newObject(); } return result; }
private void validateEventType() { final String type = jsonObject.getValue(Event.JsonFields.TYPE) .orElseGet(() -> // if type was not present (was included in V2) // take event instead and transform to V2 format, fail if "event" is not present, too extractEventTypeV1() .orElseThrow(() -> new JsonMissingFieldException(Event.JsonFields.TYPE.getPointer())) ); if (!expectedType.equals(type)) { final String msgPattern = "Event JSON was not a <{0}> event but a <{1}>!"; final String msg = MessageFormat.format(msgPattern, expectedType, type); throw new DittoJsonException(new JsonParseException(msg)); } }
/** * Creates a new {@code Resource} object based on the given {@code resourceKey} and {@code jsonValue}. * * @param resourceKey the JSON key which is assumed to be the path of a Resource prefixed with a type. * @param jsonValue the JSON value containing the effected permissions for the Resource. This value is supposed to * be a {@link JsonObject}. * @return a new {@code Resource} object. * @throws NullPointerException if any argument is {@code null}. * @throws DittoJsonException if {@code jsonValue} is not a JSON object or the JSON has not the expected format. */ public static Resource of(final ResourceKey resourceKey, final JsonValue jsonValue) { checkNotNull(jsonValue, "JSON value"); final EffectedPermissions effectedPermissions = Optional.of(jsonValue) .filter(JsonValue::isObject) .map(JsonValue::asObject) .map(object -> wrapJsonRuntimeException(() -> ImmutableEffectedPermissions.fromJson(object))) .orElseThrow(() -> new DittoJsonException(JsonParseException.newBuilder() .message("The JSON object for the 'permissions' (grant/revoke) of the 'resource' '" + resourceKey + "' is missing or not an object.") .build())); return of(resourceKey, effectedPermissions); }
/** * Creates a new {@code AclEntry} object from the specified JSON object. If, for any reason, the specified JSON * object contains more than one field with Authorization Subject/permissions pairs only the first field is used * while all remaining fields are ignored. * * @param jsonObject a JSON object which provides the data for the ACL entry to be created. * @return a new ACL entry which is initialised with the extracted data from {@code jsonObject}. * @throws NullPointerException if {@code jsonObject} is {@code null}. * @throws DittoJsonException if {@code jsonObject} <ul> <li>is empty,</li> <li>contains only a field with the schema * version</li> <li>or it contains more than two fields.</li> </ul> */ public static AclEntry fromJson(final JsonObject jsonObject) { checkNotNull(jsonObject, "JSON object"); return jsonObject.stream() .filter(field -> !Objects.equals(field.getKey(), JsonSchemaVersion.getJsonKey())) .findFirst() .map(field -> ImmutableAclEntry.of(field.getKey(), field.getValue())) .orElseThrow(() -> new DittoJsonException(JsonMissingFieldException.newBuilder() .message("The JSON object for 'aclEntry' is missing.") .build())); }
/** * Creates a new {@code AclEntry} object from the specified JSON object. If, for any reason, the specified JSON * object contains more than one field with Authorization Subject/permissions pairs only the first field is used * while all remaining fields are ignored. * * @param jsonObject a JSON object which provides the data for the ACL entry to be created. * @return a new ACL entry which is initialised with the extracted data from {@code jsonObject}. * @throws NullPointerException if {@code jsonObject} is {@code null}. * @throws DittoJsonException if {@code jsonObject} <ul> <li>is empty,</li> <li>contains only a field with the schema * version</li> <li>or it contains more than two fields.</li> </ul> */ public static AclEntry fromJson(final JsonObject jsonObject) { checkNotNull(jsonObject, "JSON object"); return jsonObject.stream() .filter(field -> !Objects.equals(field.getKey(), JsonSchemaVersion.getJsonKey())) .findFirst() .map(field -> ImmutableAclEntry.of(field.getKey(), field.getValue())) .orElseThrow(() -> new DittoJsonException(JsonMissingFieldException.newBuilder() .message("The JSON object for 'aclEntry' is missing.") .build())); }
private static DittoRuntimeException buildError(final WithDittoHeaders withDittoHeaders) { final JsonParseException jsonException = JsonParseException.newBuilder() .message("JSON contains forbidden character '\\u0000'") .build(); return new DittoJsonException(jsonException).setDittoHeaders(withDittoHeaders.getDittoHeaders()); } }
private static void validate(final CharSequence jsonKey, final JsonValue jsonValue) { checkNotNull(jsonKey, "JSON key"); checkNotNull(jsonValue, "JSON value"); final String msgTemplate = "Expected for Authorization Subject ''{0}'' a JSON object containing all of {1}" + " but got <{2}>!"; final Supplier<String> descriptionSupplier = () -> MessageFormat.format(msgTemplate, jsonKey, Permission.allToString(), jsonValue); if (!jsonValue.isObject()) { throw new DittoJsonException(JsonParseException.newBuilder() // .description(descriptionSupplier) // .build()); } final JsonObject permissionsJsonObject = jsonValue.asObject(); if (permissionsJsonObject.isEmpty()) { throw AclEntryInvalidException.newBuilder() // .description(descriptionSupplier) // .build(); } }
private static void validate(final CharSequence jsonKey, final JsonValue jsonValue) { checkNotNull(jsonKey, "JSON key"); checkNotNull(jsonValue, "JSON value"); final String msgTemplate = "Expected for Authorization Subject ''{0}'' a JSON object containing all of {1}" + " but got <{2}>!"; final Supplier<String> descriptionSupplier = () -> MessageFormat.format(msgTemplate, jsonKey, Permission.allToString(), jsonValue); if (!jsonValue.isObject()) { throw new DittoJsonException(JsonParseException.newBuilder() // .description(descriptionSupplier) // .build()); } final JsonObject permissionsJsonObject = jsonValue.asObject(); if (permissionsJsonObject.isEmpty()) { throw AclEntryInvalidException.newBuilder() // .description(descriptionSupplier) // .build(); } }