Skip to content

Commit 6ef0a4c

Browse files
committed
#1562 Jackson is too smart, complecting things, safe when field and accessor names different
1 parent ef928dd commit 6ef0a4c

3 files changed

Lines changed: 68 additions & 22 deletions

File tree

value-fixture/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@
163163
<artifactId>jspecify</artifactId>
164164
<version>1.0.0</version>
165165
</dependency>
166+
<dependency>
167+
<groupId>com.fasterxml.jackson.dataformat</groupId>
168+
<artifactId>jackson-dataformat-xml</artifactId>
169+
<version>${jackson.version}</version>
170+
<scope>test</scope>
171+
</dependency>
166172
</dependencies>
167173
<build>
168174
<plugins>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.immutables.fixture.jackson;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
8+
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
9+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
10+
import org.immutables.value.Value;
11+
import org.junit.Test;
12+
import static org.immutables.check.Checkers.check;
13+
14+
public class XmlNonForcePropertyNamesTest {
15+
16+
@Target({ElementType.PACKAGE, ElementType.TYPE})
17+
@Retention(RetentionPolicy.CLASS) // Make it class retention for incremental compilation
18+
@JsonSerialize
19+
@Value.Style(
20+
forceJacksonPropertyNames = false // otherwise we can't use RosettaNamingStrategies
21+
)
22+
@interface CustomStyle {}
23+
24+
@Value.Immutable
25+
@CustomStyle
26+
public interface MyObject {
27+
@JacksonXmlProperty(isAttribute = true)
28+
String getPlaceholder();
29+
}
30+
31+
@Test
32+
public void itWorks() throws Exception {
33+
XmlMapper xmlMapper = new XmlMapper();
34+
xmlMapper.registerModule(new com.fasterxml.jackson.datatype.jdk8.Jdk8Module());
35+
ImmutableMyObject object = xmlMapper.readValue(
36+
"<MyObject placeholder=\"This is a placeholder\" />", ImmutableMyObject.class);
37+
38+
check(object.getPlaceholder()).is("This is a placeholder");
39+
}
40+
}

value-processor/src/org/immutables/value/processor/Immutables.generator

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,44 +3354,44 @@ static final [output.linesShortable]class Json[type.generics]
33543354
[for v in type.settableAttributes if not v.jacksonAnyGetter]
33553355
[if v.encoding]
33563356
[if v.instantiation.supportsDefaultValue]
3357-
[forceJsonIgnore][v.type] [v.name] = [rr.defaultValue v];
3357+
[forceJsonIgnore][v.type] _[v.name] = [rr.defaultValue v];
33583358
[else]
3359-
[forceJsonIgnore][atNullable v][v.type] [v.name];
3359+
[forceJsonIgnore][atNullable v][v.type] _[v.name];
33603360
[/if]
33613361
[else if v.optionalType]
3362-
[forceJsonIgnore][atNullable v][v.type] [v.name] = [optionalEmpty v];
3362+
[forceJsonIgnore][atNullable v][v.type] _[v.name] = [optionalEmpty v];
33633363
[else if v.collectionType or v.mapType]
3364-
[forceJsonIgnore][atNullable v][v.type] [v.name] = [emptyImmutableInstance v ''];
3364+
[forceJsonIgnore][atNullable v][v.type] _[v.name] = [emptyImmutableInstance v ''];
33653365
[else if v.primitive]
3366-
[forceJsonIgnore][v.type] [v.name];
3366+
[forceJsonIgnore][v.type] _[v.name];
33673367
[else]
3368-
[forceJsonIgnore][atNullable v][v.type] [v.name];
3368+
[forceJsonIgnore][atNullable v][v.type] _[v.name];
33693369
[/if]
33703370
[if v.primitive or (v.requiresTrackIsSet andnot v.jacksonAnyGetter)]
3371-
[forceJsonIgnore]boolean [disambiguateField type (v.name 'IsSet')];
3371+
[forceJsonIgnore]boolean [v.name]IsSet;
33723372
[/if]
33733373
[/for]
33743374
[for v in type.settableAttributes if v.jacksonAnyGetter]
3375-
[forceJsonIgnore]final [v.type] [v.name] = new java.util.HashMap[v.genericArgs]();
3375+
[forceJsonIgnore]final [v.type] _[v.name] = new java.util.HashMap[v.genericArgs]();
33763376
[/for]
33773377
[for v in type.settableAttributes if not v.jacksonAnyGetter]
33783378

33793379
[eachLine v.annotations]
33803380
[eachLine v.initializerInjectedAnnotations]
33813381
public void [v.names.beanSet]([v.atNullability][v.type] [v.name]) {
3382-
this.[v.name] = [v.name];
3382+
this._[v.name] = [v.name];
33833383
[if v.primitive]
3384-
this.[disambiguateField type (v.name 'IsSet')] = true;
3384+
this.[v.name]IsSet = true;
33853385
[else if v.requiresTrackIsSet andnot v.jacksonAnyGetter]
3386-
this.[disambiguateField type (v.name 'IsSet')] = [if v.nullable]true[else]null != [v.name][/if];
3386+
this.[v.name]IsSet = [if v.nullable]true[else]null != [v.name][/if];
33873387
[/if]
33883388
}
33893389
[/for]
33903390
[for v in type.settableAttributes if v.jacksonAnyGetter]
33913391

33923392
@[jackson].annotation.JsonAnySetter
33933393
public void set[toUpper v.name]([v.wrappedFirstElementType] key, [v.wrappedSecondaryElementType] value) {
3394-
this.[v.name].put(key, value);
3394+
this._[v.name].put(key, value);
33953395
}
33963396
[/for]
33973397
[for signature in type.nonAttributeAbstractMethodSignatures]
@@ -3428,18 +3428,18 @@ static[type.generics.def] [type.typeImmutable.relative] fromJson(Json[type.gener
34283428
[type.typeBuilder.relative] builder = [castBuildStagedBuilder type][type.factoryBuilder.relative]()[/castBuildStagedBuilder];
34293429
[for v in type.settableAttributes]
34303430
[if v.requiresTrackIsSet or v.primitive]
3431-
if (json.[disambiguateField type (v.name 'IsSet')]) {
3431+
if (json.[v.name]IsSet) {
34323432
[else]
3433-
if (json.[v.name] != null) {
3433+
if (json._[v.name] != null) {
34343434
[/if]
34353435
[if v.encoding]
3436-
builder.[rr.builderCopyFrom v](json.[v.name]);
3436+
builder.[rr.builderCopyFrom v](json._[v.name]);
34373437
[else if v.collectionType]
3438-
builder.[v.names.addAll](json.[v.name]);
3438+
builder.[v.names.addAll](json._[v.name]);
34393439
[else if v.mapType]
3440-
builder.[v.names.putAll](json.[v.name]);
3440+
builder.[v.names.putAll](json._[v.name]);
34413441
[else]
3442-
builder.[v.names.init](json.[v.name]);
3442+
builder.[v.names.init](json._[v.name]);
34433443
[/if]
34443444
}
34453445
[/for]
@@ -3449,19 +3449,19 @@ static[type.generics.def] [type.typeImmutable.relative] fromJson(Json[type.gener
34493449
[else]
34503450
[let varDecl][if type.withSettableAfterConstruction][atVar type][/if][type.typeImmutable.relative] instance[/let]
34513451
[if type.useConstructor]
3452-
[varDecl] = [cast][type.factoryOf.relative]([for v in type.constructorArguments][if not for.first], [/if]json.[v.name][/for]);
3452+
[varDecl] = [cast][type.factoryOf.relative]([for v in type.constructorArguments][if not for.first], [/if]json._[v.name][/for]);
34533453
[else if type.useSingleton]
34543454
[varDecl] = [cast][type.factoryInstance.relative]();
34553455
[else]
34563456
[output.error]Cannot generate JSON code when there are no builders, constructors or singletons available[/output.error]
34573457
[/if]
34583458
[for v in type.withSettableAfterConstruction]
34593459
[if v.requiresTrackIsSet or v.primitive]
3460-
if (json.[disambiguateField type (v.name 'IsSet')]) {
3460+
if (json.[v.name]IsSet) {
34613461
[else]
3462-
if (json.[v.name] != null) {
3462+
if (json._[v.name] != null) {
34633463
[/if]
3464-
instance = instance.[v.names.with](json.[v.name]);
3464+
instance = instance.[v.names.with](json._[v.name]);
34653465
}
34663466
[/for]
34673467
return instance;

0 commit comments

Comments
 (0)