Skip to content

Commit 2a3bafe

Browse files
authored
Mixin should be able to contribute introspection settings (#1064)
1 parent e37b449 commit 2a3bafe

File tree

11 files changed

+243
-1
lines changed

11 files changed

+243
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
public class MuxedEvent {
4+
String compartment;
5+
String content;
6+
7+
public MuxedEvent(String compartment, String content) {
8+
this.compartment = compartment;
9+
this.content = content;
10+
}
11+
12+
public MuxedEvent() {
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class MuxedEvent2 {
6+
@JsonProperty
7+
String compartment;
8+
@JsonProperty
9+
String content;
10+
String name;
11+
12+
public MuxedEvent2(String compartment, String content, String name) {
13+
this.compartment = compartment;
14+
this.content = content;
15+
this.name = name;
16+
}
17+
18+
public MuxedEvent2() {
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
public class MuxedEvent3 {
4+
String compartment;
5+
String content;
6+
7+
public MuxedEvent3(String compartment, String content) {
8+
this.compartment = compartment;
9+
this.content = content;
10+
}
11+
12+
public MuxedEvent3() {
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
import io.micronaut.core.annotation.Introspected;
4+
import io.micronaut.serde.annotation.SerdeImport;
5+
6+
@Introspected(accessKind = Introspected.AccessKind.FIELD, visibility = Introspected.Visibility.ANY)
7+
class MuxedEvent3Mixin {
8+
}
9+
10+
@SerdeImport(mixin = MuxedEvent3Mixin.class, value = MuxedEvent3.class)
11+
class TestMixin3 {
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
import io.micronaut.core.annotation.Introspected;
4+
import io.micronaut.serde.annotation.SerdeImport;
5+
import io.micronaut.serde.jackson.mixin.outer.MuxedEvent4;
6+
7+
@Introspected(accessKind = Introspected.AccessKind.FIELD, visibility = Introspected.Visibility.ANY, targetPackage = "io.micronaut.serde.jackson.mixin.outer")
8+
public class MuxedEvent4Mixin {
9+
}
10+
11+
@SerdeImport(mixin = MuxedEvent4Mixin.class, value = MuxedEvent4.class)
12+
class TestMixin4 {
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.micronaut.serde.jackson.mixin;
2+
3+
import io.micronaut.core.annotation.Introspected;
4+
import io.micronaut.serde.annotation.SerdeImport;
5+
import io.micronaut.serde.jackson.mixin.outer.MuxedEvent5;
6+
7+
@Introspected(accessKind = Introspected.AccessKind.FIELD, visibility = Introspected.Visibility.ANY, targetPackage = "io.micronaut.serde.jackson.mixin.outer")
8+
public class MuxedEvent5Mixin {
9+
10+
@io.micronaut.core.annotation.ReflectiveAccess
11+
String compartment;
12+
@io.micronaut.core.annotation.ReflectiveAccess
13+
String content;
14+
15+
}
16+
17+
@SerdeImport(mixin = MuxedEvent5Mixin.class, value = MuxedEvent5.class)
18+
class TestMixin5 {
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package io.micronaut.serde.jackson.mixin
2+
3+
4+
import io.micronaut.annotation.processing.test.AbstractTypeElementSpec
5+
import spock.lang.PendingFeature
6+
7+
class SerdeImportMixinIntrospectionSpec extends AbstractTypeElementSpec {
8+
9+
void "test import field introspection"() {
10+
when:
11+
def introspection = buildBeanIntrospection('test.$io_micronaut_serde_jackson_mixin_MuxedEvent', '''
12+
package test;
13+
14+
import io.micronaut.core.annotation.Introspected;
15+
import io.micronaut.serde.annotation.SerdeImport;
16+
import java.util.*;
17+
import java.lang.annotation.*;
18+
import static java.lang.annotation.ElementType.*;
19+
20+
@Introspected(accessKind = Introspected.AccessKind.FIELD, visibility = Introspected.Visibility.ANY)
21+
class MuxedEventMixin {
22+
}
23+
24+
@SerdeImport(mixin = MuxedEventMixin.class, value = io.micronaut.serde.jackson.mixin.MuxedEvent.class)
25+
class Test {
26+
}
27+
28+
29+
''')
30+
31+
then:
32+
introspection != null
33+
introspection.getBeanType().getName() == "io.micronaut.serde.jackson.mixin.MuxedEvent"
34+
introspection.getBeanProperties().size() == 2
35+
introspection.getBeanProperties().collect { it.name } == ['compartment', "content"]
36+
}
37+
38+
@PendingFeature(reason = "includedAnnotations is not used in PropertyQuery")
39+
void "test import field introspection 2"() {
40+
when:
41+
def introspection = buildBeanIntrospection('test.$io_micronaut_serde_jackson_mixin_MuxedEvent2', '''
42+
package test;
43+
44+
import com.fasterxml.jackson.annotation.JsonProperty;
45+
import io.micronaut.core.annotation.Introspected;
46+
import io.micronaut.serde.annotation.SerdeImport;
47+
import java.util.*;
48+
import java.lang.annotation.*;
49+
import static java.lang.annotation.ElementType.*;
50+
51+
@Introspected(accessKind = Introspected.AccessKind.FIELD, visibility = Introspected.Visibility.ANY, includedAnnotations = JsonProperty.class)
52+
class MuxedEventMixin {
53+
}
54+
55+
@SerdeImport(mixin = MuxedEventMixin.class, value = io.micronaut.serde.jackson.mixin.MuxedEvent2.class)
56+
class Test {
57+
}
58+
59+
60+
''')
61+
62+
then:
63+
introspection != null
64+
introspection.getBeanType().getName() == "io.micronaut.serde.jackson.mixin.MuxedEvent2"
65+
introspection.getBeanProperties().size() == 2
66+
introspection.getBeanProperties().collect { it.name } == ['compartment', "content"]
67+
}
68+
}
69+

Diff for: serde-jackson/src/test/groovy/io/micronaut/serde/jackson/mixin/SerdeMixinSpec.groovy

+48
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package io.micronaut.serde.jackson.mixin
22

33
import io.micronaut.context.ApplicationContext
44
import io.micronaut.serde.ObjectMapper
5+
import io.micronaut.serde.jackson.mixin.outer.MuxedEvent4
6+
import io.micronaut.serde.jackson.mixin.outer.MuxedEvent5
7+
import spock.lang.PendingFeature
58
import spock.lang.Specification
69

710
class SerdeMixinSpec extends Specification {
@@ -19,4 +22,49 @@ class SerdeMixinSpec extends Specification {
1922
cleanup:
2023
context.close()
2124
}
25+
26+
void "should serialize with mixin"() {
27+
given:
28+
def context = ApplicationContext.run()
29+
def objectMapper = context.getBean(ObjectMapper)
30+
def muxedEvent = new MuxedEvent3("c1", "text")
31+
expect:
32+
def str = objectMapper.writeValueAsString(muxedEvent)
33+
str == '{"compartment":"c1","content":"text"}'
34+
35+
cleanup:
36+
context.close()
37+
}
38+
39+
@PendingFeature(reason = "https://github.com/micronaut-projects/micronaut-core/pull/11680")
40+
void "should serialize different package with mixin"() {
41+
given:
42+
def context = ApplicationContext.run()
43+
def objectMapper = context.getBean(ObjectMapper)
44+
def muxedEvent = new MuxedEvent4("c1", "text")
45+
when:
46+
def str = objectMapper.writeValueAsString(muxedEvent)
47+
then:
48+
noExceptionThrown()
49+
str == '{"compartment":"c1","content":"text"}'
50+
51+
cleanup:
52+
context.close()
53+
}
54+
55+
@PendingFeature(reason = "https://github.com/micronaut-projects/micronaut-core/pull/11680")
56+
void "should serialize different package with mixin 2"() {
57+
given:
58+
def context = ApplicationContext.run()
59+
def objectMapper = context.getBean(ObjectMapper)
60+
def muxedEvent = new MuxedEvent5("c1", "text")
61+
when:
62+
def str = objectMapper.writeValueAsString(muxedEvent)
63+
then:
64+
noExceptionThrown()
65+
str == '{"compartment":"c1","content":"text"}'
66+
67+
cleanup:
68+
context.close()
69+
}
2270
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.micronaut.serde.jackson.mixin.outer;
2+
3+
public class MuxedEvent4 {
4+
String compartment;
5+
String content;
6+
7+
public MuxedEvent4(String compartment, String content) {
8+
this.compartment = compartment;
9+
this.content = content;
10+
}
11+
12+
public MuxedEvent4() {
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.micronaut.serde.jackson.mixin.outer;
2+
3+
public class MuxedEvent5 {
4+
String compartment;
5+
String content;
6+
7+
public MuxedEvent5(String compartment, String content) {
8+
this.compartment = compartment;
9+
this.content = content;
10+
}
11+
12+
public MuxedEvent5() {
13+
}
14+
}

Diff for: serde-processor/src/main/java/io/micronaut/serde/processor/SerdeAnnotationVisitor.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,12 @@ private void handleClassImport(VisitorContext context, AnnotationValue<SerdeImpo
822822
}
823823

824824
private void visitMixin(ClassElement mixinType, ClassElement type) {
825+
AnnotationValue<Introspected> introspectedAnnotation = mixinType.getAnnotation(Introspected.class);
826+
if (introspectedAnnotation != null) {
827+
type.annotate(introspectedAnnotation);
828+
// We don't need to introspect the mixin
829+
mixinType.removeAnnotation(Introspected.class);
830+
}
825831
mixinType.getAnnotationNames()
826832
.stream().filter(n -> n.startsWith("io.micronaut.serde"))
827833
.forEach(n -> {
@@ -835,7 +841,6 @@ private void visitMixin(ClassElement mixinType, ClassElement type) {
835841
ElementQuery.ALL_FIELDS
836842
.onlyInstance()
837843
.onlyDeclared()
838-
.annotated((ann) -> ann.hasAnnotation(SerdeConfig.class))
839844
).stream().collect(Collectors.toMap(
840845
FieldElement::getName,
841846
(e) -> e

0 commit comments

Comments
 (0)