Skip to content
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

Add extension jackson-jr-extension-javatime to support (some) Java 8 date/time types #111

Merged
merged 13 commits into from
Feb 19, 2024
Merged
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Project is composed of multiple Maven sub-modules, each corresponding to a jar:
* [jr-retrofit2](../../tree/master/jr-retrofit2) contains `jackson-jr` - based handlers for [Retrofit 2](https://square.github.io/retrofit/) library
* Depends on `jackson-jr` and `Retrofit` API jars, and indirectly on `jackson-core`
* [jr-annotation-support](../../tree/master/jr-annotation-support) contains extension with support for a subset of core [Jackson annotations](../../../jackson-annotations)
* [jr-extension-javatime](../../tree/master/jr-extension-javatime) contains extension with support for a subset of Java 8 Date/Time types (e.g. `LocalDateTime`)
* jr-all creates an "uber-jar" that contains individual modules along with all their dependencies:
* `jr-objects` classes as-is, without relocating
* `jr-stree` classes as-is, without relocating
Expand Down
54 changes: 54 additions & 0 deletions jr-extension-javatime/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Overview

This module extends the functionality of jackson-jr by adding support for (a subset of) Java 8 Date/Time types (value types in JDK `java.time` package).

### Status

Added in Jackson 2.17.

### Usage
To be able to use supported annotations, you need to register extension like so:
```java
private static final JSON JACKSON = JSON.builder()
.register(new JacksonJrJavaTimeExtension())
.build();
```
after which you can use normal read and write operations as usual:

```java
import java.time.LocalDateTime;

public class Application {
public static void main(String[] args) {
final LocalDateTime now = LocalDateTime.now();
MyClass myObject = new MyClass(now, 'Some Other Values....');
String myObjectJsonString = JACKSON.asString(myObject);
MyClass myObjectFromJson = JACKSON.beanFrom(MyClass, myObjectJsonString);
assert myObjectFromJson.getTime().equals(now);
}
}

// ...

public class MyClass {
private LocalDateTime time;
private String otherItems;

public MyClass(LocalDateTime datetime, String others) {
//...
}

public LocalDateTime getTime() {
return time;
}
// other getters & setters
}
```

### Date Classes currently supported by `JacksonJrJavaTimeExtension`

- `java.util.LocalDateTime`

### Plans for Future

- Add support for other Java 8 Date/Time types
71 changes: 71 additions & 0 deletions jr-extension-javatime/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-parent</artifactId>
<version>2.17.0-rc1-SNAPSHOT</version>
</parent>

<artifactId>jackson-jr-extension-javatime</artifactId>
<packaging>bundle</packaging>
<description>Jackson-jr extension that adds support for Java 8 Date/Time value types such as `java.util.LocalDateTime`</description>
<url>https://github.com/FasterXML/jackson-jr</url>

<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<properties>
<!-- Looks like we need to be bit careful on OSGi exports, to avoid
accidentally double-exporting jr-objects types
-->
<osgi.export>${project.groupId}.extension.javatime;version=${project.version}</osgi.export>

<!-- for Reproducible Builds -->
<project.build.outputTimestamp>2023-11-15T22:39:39Z</project.build.outputTimestamp>
</properties>

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-objects</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>${surefire.redirectTestOutputToFile}</redirectTestOutputToFile>
<excludes>
<exclude>**/failing/*.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- 11-Mar-2019, tatu: Add basic JDK8-includable module-info, generated by Moditect -->
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
</plugin>
<!-- 05-Jul-2020, tatu: Add generation of Gradle Module Metadata -->
<plugin>
<groupId>de.jjohannes</groupId>
<artifactId>gradle-module-metadata-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fasterxml.jackson.jr.extension.javatime;

import com.fasterxml.jackson.jr.ob.JacksonJrExtension;
import com.fasterxml.jackson.jr.ob.api.ExtensionContext;

public class JacksonJrJavaTimeExtension extends JacksonJrExtension {
final static JavaTimeReaderWriterProvider DEFAULT_RW_PROVIDER = new JavaTimeReaderWriterProvider();

private JavaTimeReaderWriterProvider readerWriterProvider = DEFAULT_RW_PROVIDER;

@Override
protected void register(ExtensionContext ctxt) {
ctxt.insertProvider(readerWriterProvider);
}

public JacksonJrJavaTimeExtension with(JavaTimeReaderWriterProvider p) {
readerWriterProvider = p;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.fasterxml.jackson.jr.extension.javatime;

import com.fasterxml.jackson.jr.ob.api.ReaderWriterProvider;
import com.fasterxml.jackson.jr.ob.api.ValueReader;
import com.fasterxml.jackson.jr.ob.api.ValueWriter;
import com.fasterxml.jackson.jr.ob.impl.JSONReader;
import com.fasterxml.jackson.jr.ob.impl.JSONWriter;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* Provider for {@link ValueReader}s and {@link ValueWriter}s for Date/Time
* types supported by Java Time Extension.
*/
public class JavaTimeReaderWriterProvider extends ReaderWriterProvider
{
private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

public JavaTimeReaderWriterProvider() { }

@Override
public ValueReader findValueReader(JSONReader readContext, Class<?> type) {
return LocalDateTime.class.isAssignableFrom(type) ? new LocalDateTimeValueReader(dateTimeFormatter) : null;
}

@Override
public ValueWriter findValueWriter(JSONWriter writeContext, Class<?> type) {
return LocalDateTime.class.isAssignableFrom(type) ? new LocalDateTimeValueWriter(dateTimeFormatter) : null;
}

/**
* Method for reconfiguring {@link DateTimeFormatter} used for reading/writing
* following Date/Time value types:
*<ul>
* <li>{@code java.time.LocalDateTime}
* </li>
*</ul>
*
* @param formatter
*
* @return This provider instance for call chaining
*/
public JavaTimeReaderWriterProvider withDateTimeFormatter(DateTimeFormatter formatter) {
dateTimeFormatter = formatter;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.fasterxml.jackson.jr.extension.javatime;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.jr.ob.api.ValueReader;
import com.fasterxml.jackson.jr.ob.impl.JSONReader;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeValueReader extends ValueReader {
private final DateTimeFormatter formatter;

public LocalDateTimeValueReader(DateTimeFormatter formatter) {
super(LocalDateTime.class);
this.formatter = formatter;
}

@Override
public Object read(JSONReader reader, JsonParser p) throws IOException {
return LocalDateTime.parse(p.getText(), formatter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.fasterxml.jackson.jr.extension.javatime;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.jr.ob.api.ValueWriter;
import com.fasterxml.jackson.jr.ob.impl.JSONWriter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeValueWriter implements ValueWriter {
private final DateTimeFormatter formatter;

public LocalDateTimeValueWriter(DateTimeFormatter formatter) {
this.formatter = formatter;
}

@Override
public void writeValue(JSONWriter context, JsonGenerator g, Object value) throws IOException {
String localDateTimeString = ((LocalDateTime) value).format(formatter);
context.writeValue(localDateTimeString);
}

@Override
public Class<?> valueType() {
return LocalDateTime.class;
}
}
8 changes: 8 additions & 0 deletions jr-extension-javatime/src/main/resources/META-INF/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This copy of Jackson-jr library is licensed under the
Apache (Software) License, version 2.0 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivative works.

You may obtain a copy of the License at:

http://www.apache.org/licenses/LICENSE-2.0
17 changes: 17 additions & 0 deletions jr-extension-javatime/src/main/resources/META-INF/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Jackson JSON processor

Jackson is a high-performance, Free/Open Source JSON processing library.
It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
been in development since 2007.
It is currently developed by a community of developers.

## Licensing

Jackson components are licensed under Apache (Software) License, version 2.0,
as per accompanying LICENSE file.

## Credits

A list of contributors may be found from CREDITS file, which is included
in some artifacts (usually source distributions); but is always available
from the source code management (SCM) system project uses.
6 changes: 6 additions & 0 deletions jr-extension-javatime/src/moditect/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module com.fasterxml.jackson.jr.extension.javatime {
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.jr.ob;

exports com.fasterxml.jackson.jr.extension.javatime;
}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<module>jr-retrofit2</module>
<module>jr-stree</module>
<module>jr-annotation-support</module>
<module>jr-extension-javatime</module>
<module>jr-all</module>
</modules>

Expand Down
5 changes: 5 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ Julian Honnen (@jhonnen)
* Reported #112: `overrideStandardValueWriter` only applied to first `java.nio.file.Path`
valued field of bean
(2.17.0)

@Shounaks

* Contributed implf ro #100: Add support for `java.time` (Java 8 date/time) types
(2.17.0)
3 changes: 3 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Modules:

#78: Deserializes "null" to "0.0" for `java.lang.Double` (wrapper)
(reported by @bill-phast)
#100: Add support for `java.time` (Java 8 date/time) types
(requested by @sebastian-zero)
(contributed by @Shounaks)
#112: `overrideStandardValueWriter` only applied to first `java.nio.file.Path`
valued field of bean
(reported by Julian H)
Expand Down