mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 08:15:48 +00:00
Merge branch 'liampace-issue-3936'
This commit is contained in:
5 files changed
+188
-18
No files matched your search
@@ -62,9 +62,23 @@ import lombok.spi.Provides;
|
||||
@HandlerPriority(-512) // Above Handle(Super)Builder's level (builders must be already generated).
|
||||
public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
|
||||
private static final char[][] JSON_POJO_BUILDER_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder");
|
||||
private static final char[][] JSON_DESERIALIZE_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.databind.annotation.JsonDeserialize");
|
||||
private static final char[][] JSON_PROPERTY_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.annotation.JsonProperty");
|
||||
private static enum JacksonAnnotations {
|
||||
JSON_POJO_BUILDER("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder"),
|
||||
JSON_DESERIALIZE("com.fasterxml.jackson.databind.annotation.JsonDeserialize"),
|
||||
JSON_PROPERTY("com.fasterxml.jackson.annotation.JsonProperty"),
|
||||
JSON_IGNORE("com.fasterxml.jackson.annotation.JsonIgnore");
|
||||
|
||||
|
||||
private final String qualifiedName;
|
||||
private final char[][] annotation;
|
||||
private JacksonAnnotations(final String qualifiedName) {
|
||||
this.qualifiedName = qualifiedName;
|
||||
this.annotation = Eclipse.fromQualifiedName(qualifiedName);
|
||||
}
|
||||
private boolean isAnnotating(EclipseNode node) {
|
||||
return hasAnnotation(this.qualifiedName, node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void handle(AnnotationValues<Jacksonized> annotation, Annotation ast, EclipseNode annotationNode) {
|
||||
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.JACKSONIZED_FLAG_USAGE, "@Jacksonized");
|
||||
@@ -132,7 +146,7 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
}
|
||||
|
||||
// Insert @JsonDeserialize on annotated class.
|
||||
if (hasAnnotation("com.fasterxml.jackson.databind.annotation.JsonDeserialize", tdNode)) {
|
||||
if (JacksonAnnotations.JSON_DESERIALIZE.isAnnotating(tdNode)) {
|
||||
annotationNode.addError("@JsonDeserialize already exists on class. Either delete @JsonDeserialize, or remove @Jacksonized and manually configure Jackson.");
|
||||
return;
|
||||
}
|
||||
@@ -140,7 +154,7 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
TypeReference builderClassExpression = namePlusTypeParamsToTypeReference(builderClassNode, null, p);
|
||||
ClassLiteralAccess builderClassLiteralAccess = new ClassLiteralAccess(td.sourceEnd, builderClassExpression);
|
||||
MemberValuePair builderMvp = new MemberValuePair("builder".toCharArray(), td.sourceStart, td.sourceEnd, builderClassLiteralAccess);
|
||||
td.annotations = addAnnotation(td, td.annotations, JSON_DESERIALIZE_ANNOTATION, builderMvp);
|
||||
td.annotations = addAnnotation(td, td.annotations, JacksonAnnotations.JSON_DESERIALIZE.annotation, builderMvp);
|
||||
|
||||
// Copy annotations from the class to the builder class.
|
||||
Annotation[] copyableAnnotations = findJacksonAnnotationsOnClass(td, tdNode);
|
||||
@@ -151,7 +165,7 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
MemberValuePair withPrefixMvp = new MemberValuePair("withPrefix".toCharArray(), builderClass.sourceStart, builderClass.sourceEnd, withPrefixLiteral);
|
||||
StringLiteral buildMethodNameLiteral = new StringLiteral(buildMethodName.toCharArray(), builderClass.sourceStart, builderClass.sourceEnd, 0);
|
||||
MemberValuePair buildMethodNameMvp = new MemberValuePair("buildMethodName".toCharArray(), builderClass.sourceStart, builderClass.sourceEnd, buildMethodNameLiteral);
|
||||
builderClass.annotations = addAnnotation(builderClass, builderClass.annotations, JSON_POJO_BUILDER_ANNOTATION, withPrefixMvp, buildMethodNameMvp);
|
||||
builderClass.annotations = addAnnotation(builderClass, builderClass.annotations, JacksonAnnotations.JSON_POJO_BUILDER.annotation, withPrefixMvp, buildMethodNameMvp);
|
||||
|
||||
// @SuperBuilder? Make it package-private!
|
||||
if (superBuilderAnnotationNode != null)
|
||||
@@ -174,19 +188,33 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
// Add @JsonProperty to all fields. It will be automatically copied to the getter/setters later.
|
||||
for (EclipseNode eclipseNode : tdNode.down()) {
|
||||
if (eclipseNode.getKind() == Kind.FIELD) {
|
||||
createJsonPropertyForField(eclipseNode, annotationNode);
|
||||
if (JacksonAnnotations.JSON_PROPERTY.isAnnotating(eclipseNode) ||
|
||||
JacksonAnnotations.JSON_IGNORE.isAnnotating(eclipseNode)) {
|
||||
return;
|
||||
} else if (eclipseNode.isTransient()) {
|
||||
createJsonIgnoreForField(eclipseNode, annotationNode);
|
||||
} else {
|
||||
createJsonPropertyForField(eclipseNode, annotationNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
tdNode.rebuild();
|
||||
}
|
||||
|
||||
private void createJsonPropertyForField(EclipseNode fieldNode, EclipseNode annotationNode) {
|
||||
if (hasAnnotation("com.fasterxml.jackson.annotation.JsonProperty", fieldNode)) return;
|
||||
ASTNode astNode = fieldNode.get();
|
||||
if (astNode instanceof FieldDeclaration) {
|
||||
FieldDeclaration fd = (FieldDeclaration)astNode;
|
||||
StringLiteral fieldName = new StringLiteral(fd.name, 0, 0, 0);
|
||||
((FieldDeclaration) astNode).annotations = addAnnotation(fieldNode.get(), fd.annotations, JSON_PROPERTY_ANNOTATION, fieldName);
|
||||
((FieldDeclaration) astNode).annotations = addAnnotation(fieldNode.get(), fd.annotations, JacksonAnnotations.JSON_PROPERTY.annotation, fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
private void createJsonIgnoreForField(EclipseNode fieldNode, EclipseNode annotationNode) {
|
||||
ASTNode astNode = fieldNode.get();
|
||||
if (astNode instanceof FieldDeclaration) {
|
||||
FieldDeclaration fd = (FieldDeclaration)astNode;
|
||||
((FieldDeclaration) astNode).annotations = addAnnotation(fieldNode.get(), fd.annotations, JacksonAnnotations.JSON_IGNORE.annotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,24 @@ import lombok.spi.Provides;
|
||||
@HandlerPriority(-512) // Above Handle(Super)Builder's level (builders must be already generated), but before all handlers generating getters/setters.
|
||||
public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
|
||||
private static enum JacksonAnnotations {
|
||||
JSON_POJO_BUILDER("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder"),
|
||||
JSON_DESERIALIZE("com.fasterxml.jackson.databind.annotation.JsonDeserialize"),
|
||||
JSON_PROPERTY("com.fasterxml.jackson.annotation.JsonProperty"),
|
||||
JSON_IGNORE("com.fasterxml.jackson.annotation.JsonIgnore");
|
||||
|
||||
private final String qualifiedName;
|
||||
private final String[] chainedDots;
|
||||
private JacksonAnnotations(final String qualifiedName) {
|
||||
this.qualifiedName = qualifiedName;
|
||||
this.chainedDots = qualifiedName.split("\\.");
|
||||
}
|
||||
|
||||
private boolean isAnnotating(JavacNode node) {
|
||||
return hasAnnotation(this.qualifiedName, node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void handle(AnnotationValues<Jacksonized> annotation, JCAnnotation ast, JavacNode annotationNode) {
|
||||
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.JACKSONIZED_FLAG_USAGE, "@Jacksonized");
|
||||
|
||||
@@ -100,27 +118,42 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add @JsonProperty to all fields. It will be automatically copied to the getter/setters later.
|
||||
// Add @JsonProperty to all non-transient fields. It will be automatically copied to the getter/setters later.
|
||||
// Add @JsonIgnore to all transient fields. It will be automatically copied to the getter/setters later.
|
||||
for (JavacNode javacNode : tdNode.down()) {
|
||||
if (javacNode.getKind() == Kind.FIELD) {
|
||||
createJsonPropertyForField(javacNode, annotationNode);
|
||||
if (JacksonAnnotations.JSON_PROPERTY.isAnnotating(javacNode) ||
|
||||
JacksonAnnotations.JSON_IGNORE.isAnnotating(javacNode)) {
|
||||
return;
|
||||
} else if (javacNode.isTransient()) {
|
||||
createJsonIgnoreForField(javacNode, annotationNode);
|
||||
} else {
|
||||
createJsonPropertyForField(javacNode, annotationNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createJsonPropertyForField(JavacNode fieldNode, JavacNode annotationNode) {
|
||||
if (hasAnnotation("com.fasterxml.jackson.annotation.JsonProperty", fieldNode)) {
|
||||
return;
|
||||
}
|
||||
JavacTreeMaker maker = fieldNode.getTreeMaker();
|
||||
|
||||
JCExpression jsonPropertyType = chainDots(fieldNode, "com", "fasterxml", "jackson", "annotation", "JsonProperty");
|
||||
JCExpression jsonPropertyType = chainDots(fieldNode, JacksonAnnotations.JSON_PROPERTY.chainedDots);
|
||||
JCAnnotation annotationJsonProperty = maker.Annotation(jsonPropertyType, List.<JCExpression>of(maker.Literal(fieldNode.getName())));
|
||||
recursiveSetGeneratedBy(annotationJsonProperty, annotationNode);
|
||||
JCVariableDecl fieldDecl = ((JCVariableDecl)fieldNode.get());
|
||||
fieldDecl.mods.annotations = fieldDecl.mods.annotations.append(annotationJsonProperty);
|
||||
}
|
||||
|
||||
private void createJsonIgnoreForField(JavacNode fieldNode, JavacNode annotationNode) {
|
||||
JavacTreeMaker maker = fieldNode.getTreeMaker();
|
||||
|
||||
JCExpression jsonPropertyType = chainDots(fieldNode, JacksonAnnotations.JSON_IGNORE.chainedDots);
|
||||
JCAnnotation annotationJsonProperty = maker.Annotation(jsonPropertyType, List.<JCExpression>nil());
|
||||
recursiveSetGeneratedBy(annotationJsonProperty, annotationNode);
|
||||
JCVariableDecl fieldDecl = ((JCVariableDecl)fieldNode.get());
|
||||
fieldDecl.mods.annotations = fieldDecl.mods.annotations.append(annotationJsonProperty);
|
||||
}
|
||||
|
||||
private void handleJacksonizedBuilder(JavacNode annotationNode, JavacNode annotatedNode, JavacNode tdNode, JCClassDecl td, JavacNode builderAnnotationNode, JavacNode superBuilderAnnotationNode) {
|
||||
if (builderAnnotationNode != null && superBuilderAnnotationNode != null) {
|
||||
annotationNode.addError("@Jacksonized cannot process both @Builder and @SuperBuilder on the same class.");
|
||||
@@ -164,11 +197,11 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
}
|
||||
|
||||
// Insert @JsonDeserialize on annotated class.
|
||||
if (hasAnnotation("com.fasterxml.jackson.databind.annotation.JsonDeserialize", tdNode)) {
|
||||
if (JacksonAnnotations.JSON_DESERIALIZE.isAnnotating(tdNode)) {
|
||||
annotationNode.addError("@JsonDeserialize already exists on class. Either delete @JsonDeserialize, or remove @Jacksonized and manually configure Jackson.");
|
||||
return;
|
||||
}
|
||||
JCExpression jsonDeserializeType = chainDots(annotatedNode, "com", "fasterxml", "jackson", "databind", "annotation", "JsonDeserialize");
|
||||
JCExpression jsonDeserializeType = chainDots(annotatedNode, JacksonAnnotations.JSON_DESERIALIZE.chainedDots);
|
||||
JCExpression builderClassExpression = namePlusTypeParamsToTypeReference(maker, tdNode, annotationNode.toName(builderClassName), false, List.<JCTypeParameter>nil());
|
||||
JCFieldAccess builderClassReference = maker.Select(builderClassExpression, annotatedNode.toName("class"));
|
||||
JCExpression assign = maker.Assign(maker.Ident(annotationNode.toName("builder")), builderClassReference);
|
||||
@@ -185,7 +218,7 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
builderClass.mods.annotations = builderClass.mods.annotations.appendList(copiedAnnotations);
|
||||
|
||||
// Insert @JsonPOJOBuilder on the builder class.
|
||||
JCExpression jsonPOJOBuilderType = chainDots(annotatedNode, "com", "fasterxml", "jackson", "databind", "annotation", "JsonPOJOBuilder");
|
||||
JCExpression jsonPOJOBuilderType = chainDots(annotatedNode, JacksonAnnotations.JSON_POJO_BUILDER.chainedDots);
|
||||
JCExpression withPrefixExpr = maker.Assign(maker.Ident(annotationNode.toName("withPrefix")), maker.Literal(setPrefix));
|
||||
JCExpression buildMethodNameExpr = maker.Assign(maker.Ident(annotationNode.toName("buildMethodName")), maker.Literal(buildMethodName));
|
||||
JCAnnotation annotationJsonPOJOBuilder = maker.Annotation(jsonPOJOBuilderType, List.of(withPrefixExpr, buildMethodNameExpr));
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
public class JacksonizedAccessorsTransient {
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
private transient int intValue;
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
private transient long longValue;
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
private double doubleValue;
|
||||
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public int intValue() {
|
||||
return this.intValue;
|
||||
}
|
||||
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public long longValue() {
|
||||
return this.longValue;
|
||||
}
|
||||
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public double doubleValue() {
|
||||
return this.doubleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public JacksonizedAccessorsTransient intValue(final int intValue) {
|
||||
this.intValue = intValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public JacksonizedAccessorsTransient longValue(final long longValue) {
|
||||
this.longValue = longValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@lombok.Generated
|
||||
public JacksonizedAccessorsTransient doubleValue(final double doubleValue) {
|
||||
this.doubleValue = doubleValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
public @lombok.extern.jackson.Jacksonized @lombok.experimental.Accessors(fluent = true) @lombok.Getter @lombok.Setter class JacksonizedAccessorsTransient {
|
||||
private transient @com.fasterxml.jackson.annotation.JsonIgnore int intValue;
|
||||
private transient @com.fasterxml.jackson.annotation.JsonIgnore long longValue;
|
||||
private @com.fasterxml.jackson.annotation.JsonIgnore double doubleValue;
|
||||
public JacksonizedAccessorsTransient() {
|
||||
super();
|
||||
}
|
||||
public @java.lang.SuppressWarnings("all") @lombok.Generated int intValue() {
|
||||
return this.intValue;
|
||||
}
|
||||
public @com.fasterxml.jackson.annotation.JsonIgnore @java.lang.SuppressWarnings("all") @lombok.Generated long longValue() {
|
||||
return this.longValue;
|
||||
}
|
||||
public @com.fasterxml.jackson.annotation.JsonIgnore @java.lang.SuppressWarnings("all") @lombok.Generated double doubleValue() {
|
||||
return this.doubleValue;
|
||||
}
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
public @java.lang.SuppressWarnings("all") @lombok.Generated JacksonizedAccessorsTransient intValue(final int intValue) {
|
||||
this.intValue = intValue;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
public @com.fasterxml.jackson.annotation.JsonIgnore @java.lang.SuppressWarnings("all") @lombok.Generated JacksonizedAccessorsTransient longValue(final long longValue) {
|
||||
this.longValue = longValue;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
public @com.fasterxml.jackson.annotation.JsonIgnore @java.lang.SuppressWarnings("all") @lombok.Generated JacksonizedAccessorsTransient doubleValue(final double doubleValue) {
|
||||
this.doubleValue = doubleValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@lombok.extern.jackson.Jacksonized
|
||||
@lombok.experimental.Accessors(fluent = true)
|
||||
@lombok.Getter
|
||||
@lombok.Setter
|
||||
public class JacksonizedAccessorsTransient {
|
||||
private transient int intValue;
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore private transient long longValue;
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore private double doubleValue;
|
||||
}
|
||||
Reference in new issue
Block a user