-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support @JsonFormat annotation for date-time fields #643
Support @JsonFormat annotation for date-time fields #643
Conversation
I think it looks good.
Also as @joelittlejohn mentioned earlier, if we want to conform better to the latest JSON schema spec, then any property with For me personally at least I think the generated POJOs should validate against any JSON schema validator that follows the official JSON schema validation specs when serialised. |
@OverlyExcessive are you suggesting that I need to validate the pattern we receive in |
@shravanspurohit I'm suggesting that we get rid of the |
@OverlyExcessive I am a bit concerned with this. Here is why. Firstly, this will break a lot of things for a lot of people. Right now, I can extend the ObjectMapper class and set the date format to anything I want.
And I can register this class as a json provider on my server. The date format you set here would be the global configuration which applies to all date-time fields. Secondly, people are using @jsonformat annotation to use custom format. I personally turned to this because I had to change all my (Date) fields to include date and time except the dob field where I wanted just the date. Since I was working with legacy code, changing the date format in the CustomObjectMapper to What I would like to do is figure out a way in which jsonschema2pojo can use the full extent of capabilities Jackson provides. |
What are your thoughts on this, @joelittlejohn ? |
There isn't an easy answer here, but here's what I'm thinking right now: I'd like this tool to (by default) do the right thing and create valid documents according to the rules laid out by the JSON Schema validation spec. Just as an aside, I'd also like this tool to support and encourage using the best and ubiquitous date format with no effort. We have a legacy here though and a backwards-compatibility problem - at the very least we should give people a way to keep the old behaviour. I think the best route forward would be:
|
I like this solution. So this is what I understood. Correct me if I am wrong. If If Basically, the setting Regarding the implementation, I have 2 options.
|
@shravanspurohit For me I would say either way is fine. Would be nice if we could move this PR along, let me know if you need any assistance. |
@shravanspurohit I've made a change recently to ensure that Annotators receive the generation config, and that any custom annotator that has a constructor that takes a generation config will also received it. |
joelittlejohn:master -> shravanspurohit:master
Todo: Integration tests
bcc9f1e
to
9fea42a
Compare
Integration tests implemented Fixed groovy exception. Updated comments. Updated ant documentation
9fea42a
to
2e18f83
Compare
@joelittlejohn @OverlyExcessive Its done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to do a detailed review here. There's a few things to fix. Thanks!
* Sets the 'formatDateTime' property of this class | ||
* | ||
* @param formatDateTime | ||
* Whether the fields of type `date-type` have the `@JsonFormat` annotation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think date-type
should be date-time
. Also, I think the backticks should be <code></code>
(?).
@@ -140,6 +140,8 @@ | |||
private String timeType = null; | |||
|
|||
private String dateType = null; | |||
|
|||
private boolean formatDateTime = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename this config option to formatDateTimes
? (plural) This fits better with the conventions in this project and also describes this feature better I think.
@@ -301,6 +301,12 @@ | |||
</td> | |||
<td align="center" valign="top">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">formatDateTime</td> | |||
<td valign="top">Whether the fields of type <code>date-type</code> have the <code>@JsonFormat</code> annotation with pattern set to the default value of <code>yyyy-MM-dd'T'HH:mm:ss.SSS</code> and timezone set to default value of <code>UTC</code> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date-type
should be date-time
I think
* @param propertyNode | ||
* the schema node defining this property | ||
*/ | ||
void jsonFormat(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of this method doesn't seem to use clazz
at all, could you remove this from the signature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method needs a new name I think, jsonFormat
doesn't describe what this does, it's too general. I think a good name for this method (that fits with the other methods in this interface) would be: dateField
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of this method doesn't seem to use propertyName
at all, could you remove this from the signature?
@@ -161,7 +161,10 @@ | |||
|
|||
@Parameter(names = { "-ida", "--include-dynamic-accessors" }, description = "Include dynamic getter, setter, and builder support on generated types.") | |||
private boolean includeDynamicAccessors = false; | |||
|
|||
|
|||
@Parameter(names = { "-fdt", "--format-date-time" }, description = "Whether the fields of type `date-type` have the `@JsonFormat` annotation with pattern set to the default value of `yyyy-MM-dd'T'HH:mm:ss.SSS` and timezone set to default value of `UTC`") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/date-type/date-time/
boolean formatDateTime = generationConfig.isFormatDateTime(); | ||
String iso8601DateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"; | ||
String customDateTimePattern = node.has("customDateTimePattern") == true ? node.get("customDateTimePattern").asText() : null; | ||
String timezone = node.has("customTimezone") == true ? node.get("customTimezone").asText() : "UTC"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for == true
@@ -134,6 +137,13 @@ private void propertyAnnotations(String nodeName, JsonNode node, Schema schema, | |||
ruleFactory.getNotRequiredRule().apply(nodeName, node.get("required"), generatedJavaConstruct, schema); | |||
} | |||
} | |||
|
|||
private void formatAnnotation(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode node) { | |||
String format = node.has("format") == true ? node.get("format").asText() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd simplify this to
String format = node.path("format").asText();
assertEquals(format, annotation.pattern()); | ||
// Assert that the timezones match | ||
assertEquals(timezone, annotation.timezone()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project uses the following style for if:
if (...) {
} else {
}
Could you follow this? Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
|
||
@RunWith(Parameterized.class) | ||
public class CustomDateTimeFormatIT { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate that you're trying to minimize duplication here, but this test is really hard to follow and maintain. The test itself has configurable behaviour and assertions, and it's simply very hard to see that examples are being tested.
Could you refactor this so that it not a parameterized test? These tests are good when theres is a large body of test data, but they're not good for readability and maintainability when they're being used to create a single test with many different switchable code paths.
Each example should have a clear, descriptive method (test) name. If there's duplication then you can add some helper methods to the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I felt the same but I decided to optimize it for performance. I'll make it more readable instead.
@@ -542,6 +542,17 @@ | |||
* @readonly | |||
*/ | |||
private MavenProject project; | |||
|
|||
/** | |||
* Whether the fields of type `date-type` have the `@JsonFormat` annotation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/date-type/date-time/
@joelittlejohn Done. |
Adds @jsonformat annotation to specified property. An example of the jsonschema is:
This PR is not ready to be merged. I created this to get feedback. I am still trying to get the integration tests to work.