diff --git a/formats/json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java b/formats/json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java index 020cd1c90..1383d7cb1 100644 --- a/formats/json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java +++ b/formats/json-jackson/src/main/java/io/cloudevents/jackson/CloudEventDeserializer.java @@ -41,6 +41,10 @@ class CloudEventDeserializer extends StdDeserializer { private final boolean forceExtensionNameLowerCaseDeserialization; private final boolean forceIgnoreInvalidExtensionNameDeserialization; + protected CloudEventDeserializer() { + this(false, false); + } + protected CloudEventDeserializer( boolean forceExtensionNameLowerCaseDeserialization, boolean forceIgnoreInvalidExtensionNameDeserialization diff --git a/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java index 220b94123..49467980b 100644 --- a/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java +++ b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java @@ -35,7 +35,7 @@ * using Jackson. This format is resolvable with {@link io.cloudevents.core.provider.EventFormatProvider} using the content type {@link #CONTENT_TYPE}. *

* If you want to use the {@link CloudEvent} serializers/deserializers directly in your mapper, you can use {@link #getCloudEventJacksonModule()} or - * {@link #getCloudEventJacksonModule(boolean, boolean, boolean, boolean)} to get a {@link SimpleModule} to register in your {@link ObjectMapper} instance. + * {@link #getCloudEventJacksonModule(boolean, boolean)} to get a {@link SimpleModule} to register in your {@link ObjectMapper} instance. */ public final class JsonFormat implements EventFormat { @@ -45,49 +45,41 @@ public final class JsonFormat implements EventFormat { public static final String CONTENT_TYPE = "application/cloudevents+json"; private final ObjectMapper mapper; - private final boolean forceDataBase64Serialization; - private final boolean forceStringSerialization; - private final boolean forceExtensionNameLowerCaseDeserialization; - private final boolean forceIgnoreInvalidExtensionNameDeserialization; + private final JsonFormatOptions options; /** * Create a new instance of this class customizing the serialization configuration. * * @param forceDataBase64Serialization force json base64 encoding for data * @param forceStringSerialization force string serialization for non json data field - * @param forceExtensionNameLowerCaseDeserialization force extension name deserialization for lower case - * @param forceIgnoreInvalidExtensionNameDeserialization force extension name deserialization for ignoring invalid name * @see #withForceJsonDataToBase64() * @see #withForceNonJsonDataToString() - * @see #withForceExtensionNameLowerCaseDeserialization() - * @see #withForceIgnoreInvalidExtensionNameDeserialization() */ - public JsonFormat( - boolean forceDataBase64Serialization, - boolean forceStringSerialization, - boolean forceExtensionNameLowerCaseDeserialization, - boolean forceIgnoreInvalidExtensionNameDeserialization - ) { - this.mapper = new ObjectMapper(); - this.mapper.registerModule( - getCloudEventJacksonModule( - forceDataBase64Serialization, - forceStringSerialization, - forceExtensionNameLowerCaseDeserialization, - forceIgnoreInvalidExtensionNameDeserialization - ) + public JsonFormat(boolean forceDataBase64Serialization, boolean forceStringSerialization) { + this( + JsonFormatOptions.builder() + .forceDataBase64Serialization(forceDataBase64Serialization) + .forceStringSerialization(forceStringSerialization) + .build() ); - this.forceDataBase64Serialization = forceDataBase64Serialization; - this.forceStringSerialization = forceStringSerialization; - this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization; - this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization; + } + + /** + * Create a new instance of this class customizing the serialization configuration. + * + * @param options json serialization / deserialization options + */ + public JsonFormat(JsonFormatOptions options) { + this.mapper = new ObjectMapper(); + this.mapper.registerModule(getCloudEventJacksonModule(options)); + this.options = options; } /** * Create a new instance of this class with default serialization configuration */ public JsonFormat() { - this(false, false, false, false); + this(new JsonFormatOptions()); } /** @@ -95,10 +87,12 @@ public JsonFormat() { */ public JsonFormat withForceJsonDataToBase64() { return new JsonFormat( - true, - this.forceStringSerialization, - this.forceExtensionNameLowerCaseDeserialization, - this.forceIgnoreInvalidExtensionNameDeserialization + JsonFormatOptions.builder() + .forceDataBase64Serialization(true) + .forceStringSerialization(this.options.isForceStringSerialization()) + .forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization()) + .forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization()) + .build() ); } @@ -107,10 +101,12 @@ public JsonFormat withForceJsonDataToBase64() { */ public JsonFormat withForceNonJsonDataToString() { return new JsonFormat( - this.forceDataBase64Serialization, - true, - this.forceExtensionNameLowerCaseDeserialization, - this.forceIgnoreInvalidExtensionNameDeserialization + JsonFormatOptions.builder() + .forceDataBase64Serialization(this.options.isForceDataBase64Serialization()) + .forceStringSerialization(true) + .forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization()) + .forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization()) + .build() ); } @@ -119,10 +115,12 @@ public JsonFormat withForceNonJsonDataToString() { */ public JsonFormat withForceExtensionNameLowerCaseDeserialization() { return new JsonFormat( - this.forceDataBase64Serialization, - this.forceStringSerialization, - true, - this.forceIgnoreInvalidExtensionNameDeserialization + JsonFormatOptions.builder() + .forceDataBase64Serialization(this.options.isForceDataBase64Serialization()) + .forceStringSerialization(this.options.isForceStringSerialization()) + .forceExtensionNameLowerCaseDeserialization(true) + .forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization()) + .build() ); } @@ -131,10 +129,12 @@ public JsonFormat withForceExtensionNameLowerCaseDeserialization() { */ public JsonFormat withForceIgnoreInvalidExtensionNameDeserialization() { return new JsonFormat( - this.forceDataBase64Serialization, - this.forceStringSerialization, - this.forceExtensionNameLowerCaseDeserialization, - true + JsonFormatOptions.builder() + .forceDataBase64Serialization(this.options.isForceDataBase64Serialization()) + .forceStringSerialization(this.options.isForceStringSerialization()) + .forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization()) + .forceIgnoreInvalidExtensionNameDeserialization(true) + .build() ); } @@ -180,30 +180,35 @@ public String serializedContentType() { * @return a {@link SimpleModule} with {@link CloudEvent} serializer/deserializer configured using default values. */ public static SimpleModule getCloudEventJacksonModule() { - return getCloudEventJacksonModule(false, false, false, false); + return getCloudEventJacksonModule(false, false); } /** * @param forceDataBase64Serialization force json base64 encoding for data * @param forceStringSerialization force string serialization for non json data field - * @param forceExtensionNameLowerCaseDeserialization force extension name deserialization for lower case - * @param forceIgnoreInvalidExtensionNameDeserialization force extension name deserialization for ignoring invalid name * @return a JacksonModule with CloudEvent serializer/deserializer customizing the data serialization. * @see #withForceJsonDataToBase64() * @see #withForceNonJsonDataToString() - * @see #withForceExtensionNameLowerCaseDeserialization() - * @see #withForceIgnoreInvalidExtensionNameDeserialization() */ - public static SimpleModule getCloudEventJacksonModule( - boolean forceDataBase64Serialization, - boolean forceStringSerialization, - boolean forceExtensionNameLowerCaseDeserialization, - boolean forceIgnoreInvalidExtensionNameDeserialization - ) { + public static SimpleModule getCloudEventJacksonModule(boolean forceDataBase64Serialization, boolean forceStringSerialization) { + return getCloudEventJacksonModule( + JsonFormatOptions.builder() + .forceDataBase64Serialization(forceDataBase64Serialization) + .forceStringSerialization(forceStringSerialization) + .build() + ); + } + + /** + * @param options json serialization / deserialization options + * @return a JacksonModule with CloudEvent serializer/deserializer customizing the data serialization. + */ + public static SimpleModule getCloudEventJacksonModule(JsonFormatOptions options) { final SimpleModule ceModule = new SimpleModule("CloudEvent"); - ceModule.addSerializer(CloudEvent.class, new CloudEventSerializer(forceDataBase64Serialization, forceStringSerialization)); + ceModule.addSerializer(CloudEvent.class, new CloudEventSerializer( + options.isForceDataBase64Serialization(), options.isForceStringSerialization())); ceModule.addDeserializer(CloudEvent.class, new CloudEventDeserializer( - forceExtensionNameLowerCaseDeserialization, forceIgnoreInvalidExtensionNameDeserialization)); + options.isForceExtensionNameLowerCaseDeserialization(), options.isForceIgnoreInvalidExtensionNameDeserialization())); return ceModule; } diff --git a/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormatOptions.java b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormatOptions.java new file mode 100644 index 000000000..bf18ebf31 --- /dev/null +++ b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormatOptions.java @@ -0,0 +1,99 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package io.cloudevents.jackson; + +public final class JsonFormatOptions { + private final boolean forceDataBase64Serialization; + private final boolean forceStringSerialization; + private final boolean forceExtensionNameLowerCaseDeserialization; + private final boolean forceIgnoreInvalidExtensionNameDeserialization; + + /** + * Create a new instance of this class options the serialization / deserialization. + */ + public JsonFormatOptions() { + this(false, false, false, false); + } + + JsonFormatOptions( + boolean forceDataBase64Serialization, + boolean forceStringSerialization, + boolean forceExtensionNameLowerCaseDeserialization, + boolean forceIgnoreInvalidExtensionNameDeserialization + ) { + this.forceDataBase64Serialization = forceDataBase64Serialization; + this.forceStringSerialization = forceStringSerialization; + this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization; + this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization; + } + + public static JsonFormatOptionsBuilder builder() { + return new JsonFormatOptionsBuilder(); + } + + public boolean isForceDataBase64Serialization() { + return this.forceDataBase64Serialization; + } + + public boolean isForceStringSerialization() { + return this.forceStringSerialization; + } + + public boolean isForceExtensionNameLowerCaseDeserialization() { + return this.forceExtensionNameLowerCaseDeserialization; + } + + public boolean isForceIgnoreInvalidExtensionNameDeserialization() { + return this.forceIgnoreInvalidExtensionNameDeserialization; + } + + public static class JsonFormatOptionsBuilder { + private boolean forceDataBase64Serialization = false; + private boolean forceStringSerialization = false; + private boolean forceExtensionNameLowerCaseDeserialization = false; + private boolean forceIgnoreInvalidExtensionNameDeserialization = false; + + public JsonFormatOptionsBuilder forceDataBase64Serialization(boolean forceDataBase64Serialization) { + this.forceDataBase64Serialization = forceDataBase64Serialization; + return this; + } + + public JsonFormatOptionsBuilder forceStringSerialization(boolean forceStringSerialization) { + this.forceStringSerialization = forceStringSerialization; + return this; + } + + public JsonFormatOptionsBuilder forceExtensionNameLowerCaseDeserialization(boolean forceExtensionNameLowerCaseDeserialization) { + this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization; + return this; + } + + public JsonFormatOptionsBuilder forceIgnoreInvalidExtensionNameDeserialization(boolean forceIgnoreInvalidExtensionNameDeserialization) { + this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization; + return this; + } + + public JsonFormatOptions build() { + return new JsonFormatOptions( + this.forceDataBase64Serialization, + this.forceStringSerialization, + this.forceExtensionNameLowerCaseDeserialization, + this.forceIgnoreInvalidExtensionNameDeserialization + ); + } + } +}