Lombok support
Less boilerplate code.
http://projectlombok.org/
Thanks for raising this. This is a nice idea but I see a few problems that would hold this back:
- Reducing boilerplate is less important when the code is auto-generated, the benefits of applying Lombok here are limited.
- Supporting Lombok would require significant rewriting and customizing of the parts of this project that perform code generation.
- Many Lombok code constructs cannot be achieved with CodeModel (the API we use to build our Java source). This effectively leaves us with String concatenation as the only way to build parts of the generated source code, which makes developing the plugin for (and supporting) Lombok much harder and more error prone.
- Lombok occupies a very small niche, there's a lot of effort here but the results would only be useful for a tiny population of users.
If you're interested in having a go then I'd certainly be interested to see what kind of changes you think would be useful. Would you use Lombok support if it was available or was this more an idea for discussion?
I was thinking in a parameter to tell it than I want generate the DTOs with lombok.
I can review your code to learn and maybe I'll can do some contribution to this.
What do you think.
BTW thanks for this awesome tool
I'm going to close this as I think it's just too much work and not useful to enough users. If anyone else is interested in this then please comment here, but for now I don't plan on adding this.
String concatenation? How about not generating getters and setters and putting a @Data annotation at the top of the generated classes? I've done this in CodeModel. It works fine.
@sixcorners if the @Data annotation is the only thing you would want then I don't see why this couldn't be supported.Would you use this feature?
I would want to try.. I want to do a lot of things. I don't know though. The HAR schema I see around on different websites looks different then what is used here. I think I need to look around a little more before I can say something like "I would use it" or "that is the only thing that is needed". Don't forget the not generating getters and setters part though.
@sixcorners I'm basically trying to gauge interest. I realise you may not end up using this but in terms of how popular this enhancement would be it sounds like you're a +1.
When/if I get a project working without Lombok I'll come back here and +1 this or make recommendations.
+1
Sounds like Lombok is getting more and more traction.
+1
+1
must be
I would also like to see lombok support here. Or at least an option to make fields without getters and setters private so that I can add the @Data annotation by myself.
+1. @joelittlejohn : Any update on adding Lombok support with this great tool?
What I miss in particular with the builder methods generated by jsonschema2pojo is that they don't seem to process the @Nullable annotations.
When you let Lombok generate the builder methods in the POJOs instead (through Lombok's @Builder annotation), you get explicit null-checks for free, since Lombok checks for @Nullable field annotations when it generates builder methods. This provides a nice fail-fast mechanism for fields that are never allowed to be null. The builder's .build() method will fail immediately with an IllegalArgumentException and a clear message indicating which required field was omitted. I love that in Lombok!
Right now with the current internal builder implementation of jsonschema2pojo, required fields with null values are not noticed until they are deserialized on the other end, or when explicitly validated against a schema. 😞 Please let Lombok provide the builder methods instead without reinventing the wheel. Thanks for considering this! 🙂
Having Lombok support probably won't change whether I use this or not (as you noted the boilerplate doesn't matter as much), but I think it would certainly be helpful for reading the auto-generated files. I found this project looking through auto-generated objects from this tool, and not having to visually parse the get/set methods would be wonderful.
+1
+1
What is the status of this ? I already use lombok throughout the project so for the sake of consistency I'd love to see this implemented.
I prefer creating Immutable classes with lombok's @Value and @Builder(toBuilder = true), its simple way to achieve thread-safety of POJOs.
With these annotations, if there is a way to annotate the Java POJOs generated from from json schema, and support to serialize/deserialize to/from json then it will be of great value for achieving thread-safety for generated Java POJOs .
Alternatively can we use org.jsonschema2pojo.Annotator/customAnnotator to achieve the same, will serialization/deserialization to/from json supported with such lombok annotated POJOs ?
I'd prefer to add a pluggable system for this and Lombok as an option.
Does anybody know how to apply lombok with following schema and Jackson2 annotations?
I understand how to replace hash, equals, toString and a builder if you don't like a generated one. But how do you see @Getter and @Setter usage without appying it to just every single field?
BTW, according to lombok source code, Getter.AnyAnnotation (but not onMethod) is deprecated.
{
"type": "object",
"properties": {
"field": { "type": "string" }
}
}
package example;
import java.util.HashMap;
import java.util.Map;
import javax.validation.Valid;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"field"
})
public class Address {
@JsonProperty("field")
private String field;
@JsonIgnore
@Valid
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("field")
public String getField() {
return field;
}
@JsonProperty("field")
public void setField(String field) {
this.field = field;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Address.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
sb.append("field");
sb.append('=');
sb.append(((this.field == null)?"<null>":this.field));
sb.append(',');
sb.append("additionalProperties");
sb.append('=');
sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
sb.append(',');
if (sb.charAt((sb.length()- 1)) == ',') {
sb.setCharAt((sb.length()- 1), ']');
} else {
sb.append(']');
}
return sb.toString();
}
@Override
public int hashCode() {
int result = 1;
result = ((result* 31)+((this.field == null)? 0 :this.field.hashCode()));
result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
return result;
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if ((other instanceof Address) == false) {
return false;
}
Address rhs = ((Address) other);
return (((this.field == rhs.field)||((this.field!= null)&&this.field.equals(rhs.field)))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))));
}
}
@eirnym - you're looking for the @Data annotation to add getters and setters for every field:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"field"
})
@Data
@HashCodeAndEquals
public class Address {
@JsonProperty("field")
private String field
@JsonIgnore
@Valid
@Setter(AccessLevel.PRIVATE) // setAdditionalProperties(Map) will be private
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
I suggest the following as the base template for Lombok:
@Data
@Jacksonized
@Builder
class GenericPojo {
//private AnyType anyMappedProperty;
@JsonAnySetter
@Singular("any")
private Map<String, Object> any;
}
Hi! any news about adding @Data annotation?
so what's going on?? adding lombok or customized Annotation on GeneratedClass
@joelittlejohn How's it going? It is a good idea to support lombok annotation.
+1, combining lombok capability would complement the functionality the jsonschema2pojo wants to provide. I am not very familiar with this codebase, but happy to collaborate if additional hands needed. thanks
hey everyone, i am also a fan of lombok and have been using it in various projects for years. therefore, i wanted to introduce lombok to jsonschema2pojo which i needed for a new project.
my solution approach is a generic one and therefore can be used with lombok, but is not limited to it only. therefore, it does not create a dependency to lombok within this project. i introduce a new configuration extraClassAnnotations that can be used for any annotation that the user wants to put on a java class.
the modules core and maven-plugin are adjusted. i verified that it works. ~~the other modules are future work.~~
as an example, in order to use it with lombok, the following configurations can be included:
<configuration>
....
<!-- either getters or setters have to be enabled, because jsonschema2pojo makes the fields public otherwise -->
<includeGetters>true</includeGetters>
<includeSetters>false</includeSetters>
<includeToString>false</includeToString>
<includeHashcodeAndEquals>false</includeHashcodeAndEquals>
<extraClassAnnotations>
<annotation>lombok.NoArgsConstructor</annotation>
<annotation>lombok.Setter</annotation>
<annotation>lombok.ToString</annotation>
<annotation>lombok.EqualsAndHashCode</annotation>
</extraClassAnnotations>
....
</configuration>
my work-in-progress can be found in my fork.
any hints and tips regarding testing is welcome. when the work is finished, i plan to make a PR.
edit: i adjusted other modules as well.