jsonschema2pojo icon indicating copy to clipboard operation
jsonschema2pojo copied to clipboard

Prevent single letter fields from always becoming lower case

Open Petersoj opened this issue 6 years ago • 8 comments
trafficstars

Say you have the following JSON and you're generating from JSON files:

{
  "ticker": "AAPL",
  "status": "OK",
  "adjusted": true,
  "queryCount": 55,
  "resultsCount": 2,
  "results": [
    {
      "T": "AAPL",
      "v": 31315282,
      "o": 102.87,
      "c": 103.74,
      "h": 103.82,
      "l": 102.65,
      "t": 1549314000000,
      "n": 4
    }
  ]
}

There is an upper case "T" and a lower case "t" in the "results" array. Even with propertyWordDelimiters being empty, the first "T" becomes lower case and conflicts with the second "t" causing a name conflict error which JDefinedClass so kindly throws: IllegalArgumentException: trying to create the same field twice: t This is a huge issue for JSON Schemas/Sources that are "compressed" you could say. This PR simply modifies the makeLowerCamelCase() method in NameHelper to instantly return names with one letter.

Petersoj avatar Oct 19 '19 18:10 Petersoj

Hi Jacob. How do you intend to create getters and setters for these fields?

I think if there are names that conflict in this way, we need to add underscores to the name until they do not conflict. So if a field name conflicts with an existing field, then we add an underscore and try again. The Java class would then have:

@JsonProperty("t")
private String t;
@JsonProperty("T")
private String t_;

It's the only way to avoid conflicts.

joelittlejohn avatar Oct 19 '19 19:10 joelittlejohn

@joelittlejohn Method signatures are case sensitive.

@JsonProperty("T")
private String T;
@JsonProperty("t")
private String t;

public String getT() {
    return T;
}
public String gett() {
    return t;
}

The above compiles fine. Am I missing something here?

Petersoj avatar Oct 19 '19 20:10 Petersoj

@joelittlejohn I see what you're talking about now. There is a capitalize() method that gets called always when generating getter or setter method names. Not capitalizing these method names actually breaks a lot of the tests. Personally, I think we should add another configuration option to allow for the generators to either generate getters/setters with names verbatim to their corresponding field so that users can specify what to do in a situation like this.

Petersoj avatar Oct 19 '19 20:10 Petersoj

@joelittlejohn I've gone ahead and added a getterSetterExact option that will set the getters and setters of a specific field to be exactly the name of that field. I added integration tests as well. Let me know what you think.

Petersoj avatar Oct 19 '19 22:10 Petersoj

@joelittlejohn What's the status on where or not this can get merged?

Petersoj avatar Oct 29 '19 20:10 Petersoj

Hi Jacob. I think this 'getterSetterExact' is not something we want in the core of this project I'm afraid. I understand that your code above compiles, but what does the bean spec say?

We shouldn't require some additional config arg to be set to make this compile, but we need to create Java beans that are correct. I've made a suggestion for how to resolve this, that's consistent with the conventions of this project and also creates valid bean accessors and valid JSON output.

joelittlejohn avatar Oct 29 '19 21:10 joelittlejohn

@joelittlejohn Gotcha. So the the adding underscores method would be in compliance with the bean specifications? If so, I'll modify my PR to do just that. Let me know. Thanks.

Petersoj avatar Oct 29 '19 21:10 Petersoj

@Petersoj Yep, go for it. So the result will be:

@JsonProperty("t")
private String t;
@JsonProperty("T")
private String t_;

@JsonProperty("t")
public String getT() {
    return T;
}

@JsonProperty("T")
public String getT_() {
    return t;
}

You can see that java.beans.Introspector#decapitalize will decapitalize 'T' and 'T_' to the correct field.

joelittlejohn avatar Nov 04 '19 11:11 joelittlejohn