From d441be157b7d51d4694370ac7ecc502565aee6b2 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 6 Feb 2026 00:22:55 +0100 Subject: [PATCH] [jacksonized] infrastructure for previous merge resolution: Changed to the config system so you can specify jackson major version, or even multiple versions. --- src/core/lombok/ConfigurationKeys.java | 19 +++-- .../lombok/core/JacksonAnnotationType.java | 61 ++++++++++++++ .../configuration/ConfigurationDataType.java | 31 ++++--- .../core/configuration/JacksonVersion.java | 82 ++++++++----------- .../core/configuration/MappedConfigEnum.java | 26 ++++++ .../eclipse/handlers/HandleJacksonized.java | 1 - .../features/experimental/Jacksonized.html | 14 ++++ 7 files changed, 163 insertions(+), 71 deletions(-) create mode 100644 src/core/lombok/core/JacksonAnnotationType.java create mode 100644 src/core/lombok/core/configuration/MappedConfigEnum.java diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index a3259d4f..997c550b 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2025 The Project Lombok Authors. + * Copyright (C) 2013-2026 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -702,7 +702,7 @@ public class ConfigurationKeys { * If set, any usage of {@code @WithBy} results in a warning / error. */ public static final ConfigurationKey WITHBY_FLAG_USAGE = new ConfigurationKey("lombok.withBy.flagUsage", "Emit a warning or error if @WithBy is used.") {}; - + // ----- Jacksonized ----- /** @@ -712,15 +712,16 @@ public class ConfigurationKeys { */ public static final ConfigurationKey JACKSONIZED_FLAG_USAGE = new ConfigurationKey("lombok.jacksonized.flagUsage", "Emit a warning or error if @Jacksonized is used.") {}; - /** - * lombok configuration: {@code lombok.jacksonized.jacksonVersion} = {@code 2} | {@code 3} | {@code 2_3}. - * - * The jackson major version to use. + * lombok configuration: {@code lombok.jacksonized.jacksonVersion} += {@code 2} / {@code 3}. + * + * Which version of the jackson annotations to generate. + * + * If no values specified: Generate version 2 and emit a warning to explicitly choose a jackson version in your {@code lombok.config}. */ - public static final ConfigurationKey JACKSONIZED_JACKSON_VERSION = new ConfigurationKey("lombok.jacksonized.jacksonVersion", "Select the jackson major version to use (default: 2)") {}; - - + public static final ConfigurationKey> JACKSONIZED_JACKSON_VERSION = new ConfigurationKey>("lombok.jacksonized.jacksonVersion", "The jackson major version(s) to generate (default: 2 + warning)") {}; + + // ----- Configuration System ----- /** diff --git a/src/core/lombok/core/JacksonAnnotationType.java b/src/core/lombok/core/JacksonAnnotationType.java new file mode 100644 index 00000000..306f28cc --- /dev/null +++ b/src/core/lombok/core/JacksonAnnotationType.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2026 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.core; + +public enum JacksonAnnotationType { + JSON_POJO_BUILDER2("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder"), + JSON_POJO_BUILDER3("tools.jackson.databind.annotation.JsonPOJOBuilder"), + JSON_DESERIALIZE2("com.fasterxml.jackson.databind.annotation.JsonDeserialize"), + JSON_DESERIALIZE3("tools.jackson.databind.annotation.JsonDeserialize"), + JSON_PROPERTY2("com.fasterxml.jackson.annotation.JsonProperty"), + JSON_IGNORE2("com.fasterxml.jackson.annotation.JsonIgnore"), + ; + + private final String qualifiedName; + private final String[] qualifiedNameStringArr; + private final char[][] qualifiedNameCharArrArr; + + private JacksonAnnotationType(final String qualifiedName) { + this.qualifiedName = qualifiedName; + String[] parts = qualifiedName.split("\\."); + this.qualifiedNameStringArr = parts; + char[][] caa = new char[parts.length][]; + for (int i = 0; i < parts.length; i++) { + caa[i] = parts[i].toCharArray(); + } + this.qualifiedNameCharArrArr = caa; + } + + public String getQualifiedName() { + return qualifiedName; + } + + // Do not modify the returned array. + public String[] getQualifiedNameAsStringArray() { + return qualifiedNameStringArr; + } + + // Do not modify the returned array. + public char[][] getQualifiednameAsCharArrayArray() { + return qualifiedNameCharArrArr; + } +} diff --git a/src/core/lombok/core/configuration/ConfigurationDataType.java b/src/core/lombok/core/configuration/ConfigurationDataType.java index 50b47a2e..4c05f28d 100644 --- a/src/core/lombok/core/configuration/ConfigurationDataType.java +++ b/src/core/lombok/core/configuration/ConfigurationDataType.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2019 The Project Lombok Authors. + * Copyright (C) 2013-2026 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -102,23 +102,30 @@ public final class ConfigurationDataType { SIMPLE_TYPES = map; } - private static ConfigurationValueParser enumParser(Type enumType) { + private static ConfigurationValueParser enumParser(final Type enumType) { final Class type = (Class) enumType; @SuppressWarnings("rawtypes") final Class rawType = type; return new ConfigurationValueParser() { @SuppressWarnings("unchecked") @Override public Object parse(String value) { - try { - return Enum.valueOf(rawType, value); - } catch (Exception e) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - if (Character.isUpperCase(c) && i > 0) sb.append("_"); - sb.append(Character.toUpperCase(c)); + if (enumType instanceof Class && MappedConfigEnum.class.isAssignableFrom(type)) { + for (Object enumVal : ((Class) enumType).getEnumConstants()) { + if (((MappedConfigEnum) enumVal).matches(value)) return enumVal; + } + throw new IllegalArgumentException("Invalid value: " + value); + } else { + try { + return Enum.valueOf(rawType, value); + } catch (Exception e) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + if (Character.isUpperCase(c) && i > 0) sb.append("_"); + sb.append(Character.toUpperCase(c)); + } + return Enum.valueOf(rawType, sb.toString()); } - return Enum.valueOf(rawType, sb.toString()); } } @@ -129,7 +136,7 @@ public final class ConfigurationDataType { @Override public String exampleValue() { ExampleValueString evs = type.getAnnotation(ExampleValueString.class); if (evs != null) return evs.value(); - return Arrays.toString(type.getEnumConstants()).replace(",", " |"); + return Arrays.toString(type.getEnumConstants()).replace(",", " | "); } }; } diff --git a/src/core/lombok/core/configuration/JacksonVersion.java b/src/core/lombok/core/configuration/JacksonVersion.java index 2b1efe71..58a5e52c 100644 --- a/src/core/lombok/core/configuration/JacksonVersion.java +++ b/src/core/lombok/core/configuration/JacksonVersion.java @@ -1,54 +1,38 @@ +/* + * Copyright (C) 2026 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.core.configuration; -public final class JacksonVersion implements ConfigurationValueType { - - private final boolean useJackson2; - private final boolean useJackson3; - - private static final JacksonVersion _2 = new JacksonVersion(true, false); - private static final JacksonVersion _3 = new JacksonVersion(false, true); - private static final JacksonVersion _23 = new JacksonVersion(true, true); - - public static final JacksonVersion getDefault() { - return _2; +public enum JacksonVersion implements MappedConfigEnum { + TWO, + THREE, + ; + + @Override public boolean matches(String value) { + if (this == TWO) return "2".equals(value); + return "3".equals(value); } - - public static String exampleValue() { - return "2, 3 or 2_3"; - } - - public static String description() { - return "Select the major version of the jackson framework."; - } - - public static JacksonVersion valueOf(String value) { - if (value == null || value.isEmpty()) { - return getDefault(); - } else if ("2".equals(value.trim())) { - return _2; - } else if ("3".equals(value.trim())) { - return _3; - } else if ("2_3".equals(value.trim())) { - return _23; - } else { - throw new IllegalArgumentException("Unsupported Jackson version selector."); - } - } - - private JacksonVersion(boolean useJackson2, boolean useJackson3) { - this.useJackson2 = useJackson2; - this.useJackson3 = useJackson3; - } - - public boolean useJackson2() { - return useJackson2; - } - - public boolean useJackson3() { - return useJackson3; - } - - public boolean isValid() { - return useJackson2 || useJackson3; + + @Override public String toString() { + if (this == TWO) return "2"; + return "3"; } } diff --git a/src/core/lombok/core/configuration/MappedConfigEnum.java b/src/core/lombok/core/configuration/MappedConfigEnum.java new file mode 100644 index 00000000..6f485b45 --- /dev/null +++ b/src/core/lombok/core/configuration/MappedConfigEnum.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2026 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.core.configuration; + +public interface MappedConfigEnum { + boolean matches(String value); +} diff --git a/src/core/lombok/eclipse/handlers/HandleJacksonized.java b/src/core/lombok/eclipse/handlers/HandleJacksonized.java index 316c6c88..6463cfb8 100644 --- a/src/core/lombok/eclipse/handlers/HandleJacksonized.java +++ b/src/core/lombok/eclipse/handlers/HandleJacksonized.java @@ -47,7 +47,6 @@ import lombok.core.JacksonAnnotationType; import lombok.core.AST.Kind; import lombok.core.configuration.JacksonVersion; import lombok.core.handlers.HandlerUtil; -import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; import lombok.experimental.Accessors; diff --git a/website/templates/features/experimental/Jacksonized.html b/website/templates/features/experimental/Jacksonized.html index 51e7d009..dd452132 100644 --- a/website/templates/features/experimental/Jacksonized.html +++ b/website/templates/features/experimental/Jacksonized.html @@ -39,6 +39,20 @@ public class JacksonExample {

+ <@f.confKeys> +
+ lombok.jacksonized.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Jacksonized as a warning or error if configured. +
+ lombok.jacksonized.jacksonVersion += version (default: 2 + generate warning) +
+ (Since 1.18.44) Jackson now has 2 different major versions: Jackson2, and Jackson3. Specify which version of the jackson annotations to generate.
+ If no version is chosen, lombok will generate Jackson v2 annotations and emit a warning that you should add this config key to pick which jackson version you want.
+ If transitioning from Jackson2 to Jackson3, you can ask lombok to emit both variants. See: Lombok configuration system. +
+ + <@f.smallPrint>

In particular, the annotation does the following for @(Super)Builder: