diff --git a/jackson-modules/jackson-annotations/README.md b/jackson-modules/jackson-annotations/README.md
new file mode 100644
index 0000000000..783a06605b
--- /dev/null
+++ b/jackson-modules/jackson-annotations/README.md
@@ -0,0 +1,9 @@
+## Jackson Annotations
+
+This module contains articles about Jackson annotations.
+
+### Relevant Articles:
+- [Guide to @JsonFormat in Jackson](https://www.baeldung.com/jackson-jsonformat)
+- [More Jackson Annotations](https://www.baeldung.com/jackson-advanced-annotations)
+- [Jackson – Bidirectional Relationships](https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion)
+- [Jackson JSON Views](https://www.baeldung.com/jackson-json-view-annotation)
diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml
new file mode 100644
index 0000000000..0da73e5791
--- /dev/null
+++ b/jackson-modules/jackson-annotations/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+ jackson-annotations
+ 0.0.1-SNAPSHOT
+ jackson-annotations
+
+
+ com.ossez
+ jackson-modules
+ 0.0.2-SNAPSHOT
+
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-jsonSchema
+ ${jackson.version}
+
+
+ io.rest-assured
+ json-path
+ ${rest-assured.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ jackson-annotations
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ 3.1.1
+
+
+
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java
new file mode 100644
index 0000000000..5e46c0abd5
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.bidirection;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class CustomListDeserializer extends StdDeserializer> {
+
+ private static final long serialVersionUID = 1095767961632979804L;
+
+ public CustomListDeserializer() {
+ this(null);
+ }
+
+ public CustomListDeserializer(final Class> vc) {
+ super(vc);
+ }
+
+ @Override
+ public List deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
+ return new ArrayList();
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java
new file mode 100644
index 0000000000..376aba09e3
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java
@@ -0,0 +1,32 @@
+package com.ossez.jackson.bidirection;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomListSerializer extends StdSerializer> {
+
+ private static final long serialVersionUID = 3698763098000900856L;
+
+ public CustomListSerializer() {
+ this(null);
+ }
+
+ public CustomListSerializer(final Class> t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(final List items, final JsonGenerator generator, final SerializerProvider provider) throws IOException, JsonProcessingException {
+ final List ids = new ArrayList();
+ for (final ItemWithSerializer item : items) {
+ ids.add(item.id);
+ }
+ generator.writeObject(ids);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java
new file mode 100644
index 0000000000..a3bc3af89d
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java
@@ -0,0 +1,17 @@
+package com.ossez.jackson.bidirection;
+
+public class Item {
+ public int id;
+ public String itemName;
+ public User owner;
+
+ public Item() {
+ super();
+ }
+
+ public Item(final int id, final String itemName, final User owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java
new file mode 100644
index 0000000000..d2ca1392ed
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java
@@ -0,0 +1,21 @@
+package com.ossez.jackson.bidirection;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+public class ItemWithIdentity {
+ public int id;
+ public String itemName;
+ public UserWithIdentity owner;
+
+ public ItemWithIdentity() {
+ super();
+ }
+
+ public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java
new file mode 100644
index 0000000000..9cfa9e6056
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java
@@ -0,0 +1,17 @@
+package com.ossez.jackson.bidirection;
+
+public class ItemWithIgnore {
+ public int id;
+ public String itemName;
+ public UserWithIgnore owner;
+
+ public ItemWithIgnore() {
+ super();
+ }
+
+ public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java
new file mode 100644
index 0000000000..5db219f428
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java
@@ -0,0 +1,21 @@
+package com.ossez.jackson.bidirection;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+
+public class ItemWithRef {
+ public int id;
+ public String itemName;
+
+ @JsonBackReference
+ public UserWithRef owner;
+
+ public ItemWithRef() {
+ super();
+ }
+
+ public ItemWithRef(final int id, final String itemName, final UserWithRef owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java
new file mode 100644
index 0000000000..dc889d49e8
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java
@@ -0,0 +1,17 @@
+package com.ossez.jackson.bidirection;
+
+public class ItemWithSerializer {
+ public int id;
+ public String itemName;
+ public UserWithSerializer owner;
+
+ public ItemWithSerializer() {
+ super();
+ }
+
+ public ItemWithSerializer(final int id, final String itemName, final UserWithSerializer owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java
new file mode 100644
index 0000000000..c22a765b7c
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java
@@ -0,0 +1,26 @@
+package com.ossez.jackson.bidirection;
+
+import com.ossez.jackson.bidirection.jsonview.Views;
+
+import com.fasterxml.jackson.annotation.JsonView;
+
+public class ItemWithView {
+ @JsonView(Views.Public.class)
+ public int id;
+
+ @JsonView(Views.Public.class)
+ public String itemName;
+
+ @JsonView(Views.Public.class)
+ public UserWithView owner;
+
+ public ItemWithView() {
+ super();
+ }
+
+ public ItemWithView(final int id, final String itemName, final UserWithView owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java
new file mode 100644
index 0000000000..4f7cfadc05
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java
@@ -0,0 +1,24 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class User {
+ public int id;
+ public String name;
+ public List- userItems;
+
+ public User() {
+ super();
+ }
+
+ public User(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList
- ();
+ }
+
+ public void addItem(final Item item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java
new file mode 100644
index 0000000000..90baaca4db
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java
@@ -0,0 +1,28 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+public class UserWithIdentity {
+ public int id;
+ public String name;
+ public List userItems;
+
+ public UserWithIdentity() {
+ super();
+ }
+
+ public UserWithIdentity(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithIdentity item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java
new file mode 100644
index 0000000000..19fb6b63fe
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java
@@ -0,0 +1,28 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class UserWithIgnore {
+ public int id;
+ public String name;
+
+ @JsonIgnore
+ public List userItems;
+
+ public UserWithIgnore() {
+ super();
+ }
+
+ public UserWithIgnore(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithIgnore item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java
new file mode 100644
index 0000000000..8236103627
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java
@@ -0,0 +1,28 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonManagedReference;
+
+public class UserWithRef {
+ public int id;
+ public String name;
+
+ @JsonManagedReference
+ public List userItems;
+
+ public UserWithRef() {
+ super();
+ }
+
+ public UserWithRef(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList<>();
+ }
+
+ public void addItem(final ItemWithRef item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java
new file mode 100644
index 0000000000..7b4f2d01d3
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java
@@ -0,0 +1,30 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class UserWithSerializer {
+ public int id;
+ public String name;
+
+ @JsonSerialize(using = CustomListSerializer.class)
+ @JsonDeserialize(using = CustomListDeserializer.class)
+ public List userItems;
+
+ public UserWithSerializer() {
+ super();
+ }
+
+ public UserWithSerializer(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithSerializer item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java
new file mode 100644
index 0000000000..d1835e6a4e
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java
@@ -0,0 +1,33 @@
+package com.ossez.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ossez.jackson.bidirection.jsonview.Views;
+
+import com.fasterxml.jackson.annotation.JsonView;
+
+public class UserWithView {
+ @JsonView(Views.Public.class)
+ public int id;
+
+ @JsonView(Views.Public.class)
+ public String name;
+
+ @JsonView(Views.Internal.class)
+ public List userItems;
+
+ public UserWithView() {
+ super();
+ }
+
+ public UserWithView(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithView item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java
new file mode 100644
index 0000000000..5f1dea2908
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java
@@ -0,0 +1,9 @@
+package com.ossez.jackson.bidirection.jsonview;
+
+public class Views {
+ public static class Public {
+ }
+
+ public static class Internal extends Public {
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java
new file mode 100644
index 0000000000..026d52cfaa
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java
@@ -0,0 +1,30 @@
+package com.ossez.jackson.domain;
+
+public class Person {
+
+ private String firstName;
+ private String lastName;
+
+ public Person(String firstName, String lastName) {
+ super();
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
+
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java
new file mode 100644
index 0000000000..6a18331273
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java
@@ -0,0 +1,37 @@
+package com.ossez.jackson.format;
+
+import java.util.Date;
+
+import com.ossez.jackson.domain.Person;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * @author Jay Sridhar
+ * @version 1.0
+ */
+public class User extends Person {
+ private String firstName;
+ private String lastName;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
+ private Date createdDate;
+
+ public User(String firstName, String lastName) {
+ super(firstName, lastName);
+ this.createdDate = new Date();
+ }
+
+ public Date getCreatedDate() {
+ return createdDate;
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ", locale = "en_GB")
+ public Date getCurrentDate() {
+ return new Date();
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.NUMBER)
+ public Date getDateNum() {
+ return new Date();
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java
new file mode 100644
index 0000000000..2d9fe2c1c6
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java
@@ -0,0 +1,36 @@
+package com.ossez.jackson.jsonview;
+
+import com.fasterxml.jackson.annotation.JsonView;
+
+public class Item {
+ @JsonView(Views.Public.class)
+ public int id;
+
+ @JsonView(Views.Public.class)
+ public String itemName;
+
+ @JsonView(Views.Internal.class)
+ public String ownerName;
+
+ public Item() {
+ super();
+ }
+
+ public Item(final int id, final String itemName, final String ownerName) {
+ this.id = id;
+ this.itemName = itemName;
+ this.ownerName = ownerName;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public String getOwnerName() {
+ return ownerName;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java
new file mode 100644
index 0000000000..5dd24a7790
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java
@@ -0,0 +1,22 @@
+package com.ossez.jackson.jsonview;
+
+import java.util.List;
+
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
+import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
+
+public class MyBeanSerializerModifier extends BeanSerializerModifier {
+
+ @Override
+ public List changeProperties(final SerializationConfig config, final BeanDescription beanDesc, final List beanProperties) {
+ for (int i = 0; i < beanProperties.size(); i++) {
+ final BeanPropertyWriter beanPropertyWriter = beanProperties.get(i);
+ if (beanPropertyWriter.getName() == "name") {
+ beanProperties.set(i, new UpperCasingWriter(beanPropertyWriter));
+ }
+ }
+ return beanProperties;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java
new file mode 100644
index 0000000000..95dc39bc46
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java
@@ -0,0 +1,21 @@
+package com.ossez.jackson.jsonview;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
+
+public class UpperCasingWriter extends BeanPropertyWriter {
+ final BeanPropertyWriter _writer;
+
+ public UpperCasingWriter(final BeanPropertyWriter w) {
+ super(w);
+ _writer = w;
+ }
+
+ @Override
+ public void serializeAsField(final Object bean, final JsonGenerator gen, final SerializerProvider prov) throws Exception {
+ String value = ((User) bean).name;
+ value = (value == null) ? "" : value.toUpperCase();
+ gen.writeStringField("name", value);
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java
new file mode 100644
index 0000000000..2f602c8e1b
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java
@@ -0,0 +1,27 @@
+package com.ossez.jackson.jsonview;
+
+import com.fasterxml.jackson.annotation.JsonView;
+
+public class User {
+ public int id;
+
+ @JsonView(Views.Public.class)
+ public String name;
+
+ public User() {
+ super();
+ }
+
+ public User(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java
new file mode 100644
index 0000000000..26e3c91a66
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java
@@ -0,0 +1,9 @@
+package com.ossez.jackson.jsonview;
+
+public class Views {
+ public static class Public {
+ }
+
+ public static class Internal extends Public {
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java
new file mode 100644
index 0000000000..f610d69724
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java
@@ -0,0 +1,133 @@
+package com.ossez.jackson.advancedannotations;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ossez.jackson.advancedannotations.AppendBeans.BeanWithAppend;
+import com.ossez.jackson.advancedannotations.AppendBeans.BeanWithoutAppend;
+import com.ossez.jackson.advancedannotations.IdentityReferenceBeans.BeanWithIdentityReference;
+import com.ossez.jackson.advancedannotations.IdentityReferenceBeans.BeanWithoutIdentityReference;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
+import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
+
+public class AdvancedAnnotationsUnitTest {
+ @Test
+ public void whenNotUsingJsonIdentityReferenceAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ BeanWithoutIdentityReference bean = new BeanWithoutIdentityReference(1, "Bean Without Identity Reference Annotation");
+ String jsonString = mapper.writeValueAsString(bean);
+
+ assertThat(jsonString, containsString("Bean Without Identity Reference Annotation"));
+ }
+
+ @Test
+ public void whenUsingJsonIdentityReferenceAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ BeanWithIdentityReference bean = new BeanWithIdentityReference(1, "Bean With Identity Reference Annotation");
+ String jsonString = mapper.writeValueAsString(bean);
+
+ assertEquals("1", jsonString);
+ }
+
+ @Test
+ public void whenNotUsingJsonAppendAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+
+ BeanWithoutAppend bean = new BeanWithoutAppend(2, "Bean Without Append Annotation");
+ ObjectWriter writer = mapper.writerFor(BeanWithoutAppend.class)
+ .withAttribute("version", "1.0");
+ String jsonString = writer.writeValueAsString(bean);
+
+ assertThat(jsonString, not(containsString("version")));
+ assertThat(jsonString, not(containsString("1.0")));
+ }
+
+ @Test
+ public void whenUsingJsonAppendAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+
+ BeanWithAppend bean = new BeanWithAppend(2, "Bean With Append Annotation");
+ ObjectWriter writer = mapper.writerFor(BeanWithAppend.class)
+ .withAttribute("version", "1.0");
+ String jsonString = writer.writeValueAsString(bean);
+
+ assertThat(jsonString, containsString("version"));
+ assertThat(jsonString, containsString("1.0"));
+ }
+
+ @Test
+ public void whenUsingJsonNamingAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ NamingBean bean = new NamingBean(3, "Naming Bean");
+ String jsonString = mapper.writeValueAsString(bean);
+
+ assertThat(jsonString, containsString("bean_name"));
+ }
+
+ @Test
+ public void whenUsingJsonPropertyDescriptionAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ SchemaFactoryWrapper wrapper = new SchemaFactoryWrapper();
+ mapper.acceptJsonFormatVisitor(PropertyDescriptionBean.class, wrapper);
+ JsonSchema jsonSchema = wrapper.finalSchema();
+ String jsonString = mapper.writeValueAsString(jsonSchema);
+ System.out.println(jsonString);
+ assertThat(jsonString, containsString("This is a description of the name property"));
+ }
+
+ @Test
+ public void whenUsingJsonPOJOBuilderAnnotation_thenCorrect() throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonString = "{\"id\":5,\"name\":\"POJO Builder Bean\"}";
+ POJOBuilderBean bean = mapper.readValue(jsonString, POJOBuilderBean.class);
+
+ assertEquals(5, bean.getIdentity());
+ assertEquals("POJO Builder Bean", bean.getBeanName());
+ }
+
+ @Test
+ public void whenUsingJsonTypeIdAnnotation_thenCorrect() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.enableDefaultTyping(DefaultTyping.NON_FINAL);
+ TypeIdBean bean = new TypeIdBean(6, "Type Id Bean");
+ String jsonString = mapper.writeValueAsString(bean);
+
+ assertThat(jsonString, containsString("Type Id Bean"));
+ }
+
+ @Test
+ public void whenUsingJsonTypeIdResolverAnnotation_thenCorrect() throws IOException {
+ TypeIdResolverStructure.FirstBean bean1 = new TypeIdResolverStructure.FirstBean(1, "Bean 1");
+ TypeIdResolverStructure.LastBean bean2 = new TypeIdResolverStructure.LastBean(2, "Bean 2");
+
+ List beans = new ArrayList<>();
+ beans.add(bean1);
+ beans.add(bean2);
+
+ TypeIdResolverStructure.BeanContainer serializedContainer = new TypeIdResolverStructure.BeanContainer();
+ serializedContainer.setBeans(beans);
+
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonString = mapper.writeValueAsString(serializedContainer);
+ assertThat(jsonString, containsString("bean1"));
+ assertThat(jsonString, containsString("bean2"));
+
+ TypeIdResolverStructure.BeanContainer deserializedContainer = mapper.readValue(jsonString, TypeIdResolverStructure.BeanContainer.class);
+ List beanList = deserializedContainer.getBeans();
+ assertThat(beanList.get(0), instanceOf(TypeIdResolverStructure.FirstBean.class));
+ assertThat(beanList.get(1), instanceOf(TypeIdResolverStructure.LastBean.class));
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java
new file mode 100644
index 0000000000..6f28dbe42b
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java
@@ -0,0 +1,58 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.databind.annotation.JsonAppend;
+
+public class AppendBeans {
+ public static class BeanWithoutAppend {
+ private int id;
+ private String name;
+
+ public BeanWithoutAppend(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ @JsonAppend(attrs = { @JsonAppend.Attr(value = "version") })
+ public static class BeanWithAppend {
+ private int id;
+ private String name;
+
+ public BeanWithAppend(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java
new file mode 100644
index 0000000000..a825b7c19c
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java
@@ -0,0 +1,62 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+public class IdentityReferenceBeans {
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+ public static class BeanWithoutIdentityReference {
+ private int id;
+ private String name;
+
+ public BeanWithoutIdentityReference(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+ @JsonIdentityReference(alwaysAsId = true)
+ public static class BeanWithIdentityReference {
+ private int id;
+ private String name;
+
+ public BeanWithIdentityReference(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java
new file mode 100644
index 0000000000..93b84b1c2a
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java
@@ -0,0 +1,31 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
+public class NamingBean {
+ private int id;
+ private String beanName;
+
+ public NamingBean(int id, String beanName) {
+ this.id = id;
+ this.beanName = beanName;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getBeanName() {
+ return beanName;
+ }
+
+ public void setBeanName(String beanName) {
+ this.beanName = beanName;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java
new file mode 100644
index 0000000000..682917edc5
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java
@@ -0,0 +1,51 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+
+@JsonDeserialize(builder = POJOBuilderBean.BeanBuilder.class)
+public class POJOBuilderBean {
+ private int identity;
+ private String beanName;
+
+ @JsonPOJOBuilder(buildMethodName = "createBean", withPrefix = "construct")
+ public static class BeanBuilder {
+ private int idValue;
+ private String nameValue;
+
+ public BeanBuilder constructId(int id) {
+ idValue = id;
+ return this;
+ }
+
+ public BeanBuilder constructName(String name) {
+ nameValue = name;
+ return this;
+ }
+
+ public POJOBuilderBean createBean() {
+ return new POJOBuilderBean(idValue, nameValue);
+ }
+ }
+
+ public POJOBuilderBean(int identity, String beanName) {
+ this.identity = identity;
+ this.beanName = beanName;
+ }
+
+ public int getIdentity() {
+ return identity;
+ }
+
+ public void setIdentity(int identity) {
+ this.identity = identity;
+ }
+
+ public String getBeanName() {
+ return beanName;
+ }
+
+ public void setBeanName(String beanName) {
+ this.beanName = beanName;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java
new file mode 100644
index 0000000000..b9178a2777
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java
@@ -0,0 +1,25 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.annotation.JsonPropertyDescription;
+
+public class PropertyDescriptionBean {
+ private int id;
+ @JsonPropertyDescription("This is a description of the name property")
+ private String name;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java
new file mode 100644
index 0000000000..532941c551
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java
@@ -0,0 +1,30 @@
+package com.ossez.jackson.advancedannotations;
+
+import com.fasterxml.jackson.annotation.JsonTypeId;
+
+public class TypeIdBean {
+ private int id;
+ @JsonTypeId
+ private String name;
+
+ public TypeIdBean(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java
new file mode 100644
index 0000000000..eb65f1df70
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java
@@ -0,0 +1,130 @@
+package com.ossez.jackson.advancedannotations;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+import com.fasterxml.jackson.databind.DatabindContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
+import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
+
+public class TypeIdResolverStructure {
+ public static class BeanContainer {
+ private List beans;
+
+ public List getBeans() {
+ return beans;
+ }
+
+ public void setBeans(List beans) {
+ this.beans = beans;
+ }
+ }
+
+ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
+ @JsonTypeIdResolver(BeanIdResolver.class)
+ public static class AbstractBean {
+ private int id;
+
+ protected AbstractBean() {
+ }
+
+ protected AbstractBean(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+ }
+
+ public static class FirstBean extends AbstractBean {
+ String firstName;
+
+ public FirstBean() {
+ }
+
+ public FirstBean(int id, String name) {
+ super(id);
+ setFirstName(name);
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String name) {
+ firstName = name;
+ }
+ }
+
+ public static class LastBean extends AbstractBean {
+ String lastName;
+
+ public LastBean() {
+ }
+
+ public LastBean(int id, String name) {
+ super(id);
+ setLastName(name);
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String name) {
+ lastName = name;
+ }
+ }
+
+ public static class BeanIdResolver extends TypeIdResolverBase {
+ private JavaType superType;
+
+ @Override
+ public void init(JavaType baseType) {
+ superType = baseType;
+ }
+
+ @Override
+ public Id getMechanism() {
+ return Id.NAME;
+ }
+
+ @Override
+ public String idFromValue(Object obj) {
+ return idFromValueAndType(obj, obj.getClass());
+ }
+
+ @Override
+ public String idFromValueAndType(Object obj, Class> subType) {
+ String typeId = null;
+ switch (subType.getSimpleName()) {
+ case "FirstBean":
+ typeId = "bean1";
+ break;
+ case "LastBean":
+ typeId = "bean2";
+ }
+ return typeId;
+ }
+
+ @Override
+ public JavaType typeFromId(DatabindContext context, String id) {
+ Class> subType = null;
+ switch (id) {
+ case "bean1":
+ subType = FirstBean.class;
+ break;
+ case "bean2":
+ subType = LastBean.class;
+ }
+ return context.constructSpecializedType(superType, subType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java
new file mode 100644
index 0000000000..b04ac4da9d
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java
@@ -0,0 +1,152 @@
+package com.ossez.jackson.bidirection;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import com.ossez.jackson.bidirection.jsonview.Views;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JacksonBidirectionRelationUnitTest {
+
+ @Test (expected = JsonMappingException.class)
+ public void givenBidirectionRelation_whenSerializing_thenException() throws JsonProcessingException {
+ final User user = new User(1, "John");
+ final Item item = new Item(2, "book", user);
+ user.addItem(item);
+
+ new ObjectMapper().writeValueAsString(item);
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithSerialization_thenCorrect() throws JsonProcessingException {
+ final UserWithRef user = new UserWithRef(1, "John");
+ final ItemWithRef item = new ItemWithRef(2, "book", user);
+ user.addItem(item);
+
+ final String itemJson = new ObjectMapper().writeValueAsString(item);
+ final String userJson = new ObjectMapper().writeValueAsString(user);
+
+ assertThat(itemJson, containsString("book"));
+ assertThat(itemJson, not(containsString("John")));
+
+ assertThat(userJson, containsString("John"));
+ assertThat(userJson, containsString("userItems"));
+ assertThat(userJson, containsString("book"));
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithDeserialization_thenCorrect() throws JsonProcessingException {
+ final UserWithRef user = new UserWithRef(1, "John");
+ final ItemWithRef item = new ItemWithRef(2, "book", user);
+ user.addItem(item);
+
+ final String itemJson = new ObjectMapper().writeValueAsString(item);
+ final String userJson = new ObjectMapper().writeValueAsString(user);
+
+ final ItemWithRef itemRead = new ObjectMapper().readValue(itemJson, ItemWithRef.class);
+ final UserWithRef userRead = new ObjectMapper().readValue(userJson, UserWithRef.class);
+
+ assertThat(itemRead.itemName, is("book"));
+ assertThat(itemRead.owner, nullValue());
+
+ assertThat(userRead.name, is("John"));
+ assertThat(userRead.userItems.get(0).itemName, is("book"));
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingJsonIdentityInfo_thenCorrect() throws JsonProcessingException {
+ final UserWithIdentity user = new UserWithIdentity(1, "John");
+ final ItemWithIdentity item = new ItemWithIdentity(2, "book", user);
+ user.addItem(item);
+
+ final String result = new ObjectMapper().writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("John"));
+ assertThat(result, containsString("userItems"));
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingJsonIgnore_thenCorrect() throws JsonProcessingException {
+ final UserWithIgnore user = new UserWithIgnore(1, "John");
+ final ItemWithIgnore item = new ItemWithIgnore(2, "book", user);
+ user.addItem(item);
+
+ final String result = new ObjectMapper().writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("John"));
+ assertThat(result, not(containsString("userItems")));
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingCustomSerializer_thenCorrect() throws JsonProcessingException {
+ final UserWithSerializer user = new UserWithSerializer(1, "John");
+ final ItemWithSerializer item = new ItemWithSerializer(2, "book", user);
+ user.addItem(item);
+
+ final String result = new ObjectMapper().writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("John"));
+ assertThat(result, containsString("userItems"));
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenDeserializingUsingIdentity_thenCorrect() throws JsonProcessingException, IOException {
+ final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";
+
+ final ItemWithIdentity item = new ObjectMapper().readerFor(ItemWithIdentity.class)
+ .readValue(json);
+
+ assertEquals(2, item.id);
+ assertEquals("book", item.itemName);
+ assertEquals("John", item.owner.name);
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingCustomDeserializer_thenCorrect() throws JsonProcessingException, IOException {
+ final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";
+
+ final ItemWithSerializer item = new ObjectMapper().readerFor(ItemWithSerializer.class)
+ .readValue(json);
+ assertEquals(2, item.id);
+ assertEquals("book", item.itemName);
+ assertEquals("John", item.owner.name);
+ }
+
+ @Test
+ public void givenBidirectionRelation_whenUsingPublicJsonView_thenCorrect() throws JsonProcessingException {
+ final UserWithView user = new UserWithView(1, "John");
+ final ItemWithView item = new ItemWithView(2, "book", user);
+ user.addItem(item);
+
+ final String result = new ObjectMapper().writerWithView(Views.Public.class)
+ .writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("John"));
+ assertThat(result, not(containsString("userItems")));
+ }
+
+ @Test(expected = JsonMappingException.class)
+ public void givenBidirectionRelation_whenUsingInternalJsonView_thenException() throws JsonProcessingException {
+ final UserWithView user = new UserWithView(1, "John");
+ final ItemWithView item = new ItemWithView(2, "book", user);
+ user.addItem(item);
+
+ new ObjectMapper().writerWithView(Views.Internal.class)
+ .writeValueAsString(item);
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java
new file mode 100644
index 0000000000..5771df25f7
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java
@@ -0,0 +1,37 @@
+package com.ossez.jackson.format;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.Test;
+
+import static io.restassured.path.json.JsonPath.from;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.Percentage.withPercentage;
+
+/**
+ * @author Jay Sridhar
+ * @version 1.0
+ */
+public class JsonFormatUnitTest {
+
+ @Test
+ public void whenSerializedDateFormat_thenCorrect() throws JsonProcessingException {
+
+ User user = new User("Jay", "Sridhar");
+
+ String result = new ObjectMapper().writeValueAsString(user);
+
+ // Expected to match: "2016-12-19@09:34:42.628+0000"
+ assertThat(from(result).getString("createdDate")).matches("\\d{4}\\-\\d{2}\\-\\d{2}@\\d{2}:\\d{2}:\\d{2}\\.\\d{3}\\+\\d{4}");
+
+ // Expected to be close to current time
+ long now = new Date().getTime();
+ assertThat(from(result).getLong("dateNum")).isCloseTo(now, withPercentage(10.0));
+
+ }
+}
diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java
new file mode 100644
index 0000000000..e658982009
--- /dev/null
+++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java
@@ -0,0 +1,88 @@
+package com.ossez.jackson.jsonview;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
+import com.fasterxml.jackson.databind.ser.SerializerFactory;
+
+public class JacksonJsonViewUnitTest {
+
+ @Test
+ public void whenUseJsonViewToSerialize_thenCorrect() throws JsonProcessingException {
+ final User user = new User(1, "John");
+
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);
+
+ final String result = mapper.writerWithView(Views.Public.class)
+ .writeValueAsString(user);
+
+ assertThat(result, containsString("John"));
+ assertThat(result, not(containsString("1")));
+ }
+
+ @Test
+ public void whenUsePublicView_thenOnlyPublicSerialized() throws JsonProcessingException {
+ final Item item = new Item(2, "book", "John");
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writerWithView(Views.Public.class)
+ .writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("2"));
+
+ assertThat(result, not(containsString("John")));
+ }
+
+ @Test
+ public void whenUseInternalView_thenAllSerialized() throws JsonProcessingException {
+ final Item item = new Item(2, "book", "John");
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writerWithView(Views.Internal.class)
+ .writeValueAsString(item);
+
+ assertThat(result, containsString("book"));
+ assertThat(result, containsString("2"));
+
+ assertThat(result, containsString("John"));
+ }
+
+ @Test
+ public void whenUseJsonViewToDeserialize_thenCorrect() throws IOException {
+ final String json = "{\"id\":1,\"name\":\"John\"}";
+
+ final ObjectMapper mapper = new ObjectMapper();
+
+ final User user = mapper.readerWithView(Views.Public.class)
+ .forType(User.class)
+ .readValue(json);
+ assertEquals(1, user.getId());
+ assertEquals("John", user.getName());
+ }
+
+ @Test
+ public void whenUseCustomJsonViewToSerialize_thenCorrect() throws JsonProcessingException {
+ final User user = new User(1, "John");
+ final SerializerFactory serializerFactory = BeanSerializerFactory.instance.withSerializerModifier(new MyBeanSerializerModifier());
+
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.setSerializerFactory(serializerFactory);
+
+ final String result = mapper.writerWithView(Views.Public.class)
+ .writeValueAsString(user);
+ assertThat(result, containsString("JOHN"));
+ assertThat(result, containsString("1"));
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md
new file mode 100644
index 0000000000..ca81512fa3
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/README.md
@@ -0,0 +1,13 @@
+## Jackson 转换
+
+本模块中包含有关 Jackson 转换(Jackson conversions)有关的文章。
+
+### 相关文章:
+- [Mapping a Dynamic JSON Object with Jackson](https://www.baeldung.com/jackson-mapping-dynamic-object)
+- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
+- [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json)
+- [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv)
+- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
+- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
+- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast)
+- More articles: [[<-- prev]](../jackson-conversions)
diff --git a/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml
new file mode 100644
index 0000000000..58de10fbd9
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+ jackson-conversions-2
+ 0.0.1-SNAPSHOT
+ jackson-conversions-2
+
+
+ com.ossez
+ jackson-modules
+ 0.0.2-SNAPSHOT
+
+
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson-datatype.version}
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-csv
+ ${jackson.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ jackson-conversions-2
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ 2.9.8
+
+
+
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java
new file mode 100644
index 0000000000..b907b9301f
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java
@@ -0,0 +1,57 @@
+package com.ossez.jackson.csv;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.MappingIterator;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder;
+
+public class JsonCsvConverter {
+
+ public static void JsonToCsv(File jsonFile, File csvFile) throws IOException {
+ JsonNode jsonTree = new ObjectMapper().readTree(jsonFile);
+
+ Builder csvSchemaBuilder = CsvSchema.builder();
+ JsonNode firstObject = jsonTree.elements().next();
+ firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
+ CsvSchema csvSchema = csvSchemaBuilder
+ .build()
+ .withHeader();
+
+ CsvMapper csvMapper = new CsvMapper();
+ csvMapper.writerFor(JsonNode.class)
+ .with(csvSchema)
+ .writeValue(csvFile, jsonTree);
+ }
+
+ public static void csvToJson(File csvFile, File jsonFile) throws IOException {
+ CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader();
+ CsvMapper csvMapper = new CsvMapper();
+ MappingIterator orderLines = csvMapper.readerFor(OrderLine.class)
+ .with(orderLineSchema)
+ .readValues(csvFile);
+
+ new ObjectMapper()
+ .configure(SerializationFeature.INDENT_OUTPUT, true)
+ .writeValue(jsonFile, orderLines.readAll());
+ }
+
+ public static void JsonToFormattedCsv(File jsonFile, File csvFile) throws IOException {
+ CsvMapper csvMapper = new CsvMapper();
+ CsvSchema csvSchema = csvMapper
+ .schemaFor(OrderLineForCsv.class)
+ .withHeader();
+ csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class);
+
+ OrderLine[] orderLines = new ObjectMapper()
+ .readValue(jsonFile, OrderLine[].class);
+ csvMapper.writerFor(OrderLine[].class)
+ .with(csvSchema)
+ .writeValue(csvFile, orderLines);
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java
new file mode 100644
index 0000000000..7c028aa70c
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java
@@ -0,0 +1,49 @@
+package com.ossez.jackson.csv;
+
+import java.math.BigDecimal;
+
+public class OrderLine {
+ private String item;
+ private int quantity;
+ private BigDecimal unitPrice;
+
+ public OrderLine() {
+
+ }
+
+ public OrderLine(String item, int quantity, BigDecimal unitPrice) {
+ super();
+ this.item = item;
+ this.quantity = quantity;
+ this.unitPrice = unitPrice;
+ }
+
+ public String getItem() {
+ return item;
+ }
+
+ public void setItem(String item) {
+ this.item = item;
+ }
+
+ public int getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
+
+ public BigDecimal getUnitPrice() {
+ return unitPrice;
+ }
+
+ public void setUnitPrice(BigDecimal unitPrice) {
+ this.unitPrice = unitPrice;
+ }
+
+ @Override
+ public String toString() {
+ return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]";
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java
new file mode 100644
index 0000000000..7e89d12a1c
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java
@@ -0,0 +1,25 @@
+package com.ossez.jackson.csv;
+
+import java.math.BigDecimal;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonPropertyOrder({
+ "count",
+ "name"
+})
+public abstract class OrderLineForCsv {
+
+ @JsonProperty("name")
+ private String item;
+
+ @JsonProperty("count")
+ private int quantity;
+
+ @JsonIgnore
+ private BigDecimal unitPrice;
+
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java
new file mode 100644
index 0000000000..2b1b5b995e
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java
@@ -0,0 +1,39 @@
+package com.ossez.jackson.dynamicobject;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+
+public class Product {
+
+ private String name;
+ private String category;
+ private Map details = new LinkedHashMap<>();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public Map getDetails() {
+ return details;
+ }
+
+ @JsonAnySetter
+ public void setDetail(String key, Object value) {
+ details.put(key, value);
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java
new file mode 100644
index 0000000000..5c399a8411
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java
@@ -0,0 +1,35 @@
+package com.ossez.jackson.dynamicobject;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class ProductJsonNode {
+
+ private String name;
+ private String category;
+ private JsonNode details;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public JsonNode getDetails() {
+ return details;
+ }
+
+ public void setDetails(JsonNode details) {
+ this.details = details;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java
new file mode 100644
index 0000000000..290bb50ef6
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java
@@ -0,0 +1,35 @@
+package com.ossez.jackson.dynamicobject;
+
+import java.util.Map;
+
+public class ProductMap {
+
+ private String name;
+ private String category;
+ private Map details;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public Map getDetails() {
+ return details;
+ }
+
+ public void setDetails(Map details) {
+ this.details = details;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java
new file mode 100644
index 0000000000..45d0322bfa
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java
@@ -0,0 +1,44 @@
+package com.ossez.jackson.multiplefields;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Weather {
+
+ @JsonProperty("location")
+ @JsonAlias("place")
+ private String location;
+
+ @JsonProperty("temp")
+ @JsonAlias("temperature")
+ private int temp;
+
+ @JsonProperty("outlook")
+ @JsonAlias("weather")
+ private String outlook;
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public int getTemp() {
+ return temp;
+ }
+
+ public void setTemp(int temp) {
+ this.temp = temp;
+ }
+
+ public String getOutlook() {
+ return outlook;
+ }
+
+ public void setOutlook(String outlook) {
+ this.outlook = outlook;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java
new file mode 100644
index 0000000000..9f0dd4db28
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java
@@ -0,0 +1,70 @@
+package com.ossez.jackson.tocollection;
+
+
+import java.util.Objects;
+
+public class Book {
+ private Integer bookId;
+ private String title;
+ private String author;
+
+ public Book() {}
+
+ public Book(Integer bookId, String title, String author) {
+ this.bookId = bookId;
+ this.title = title;
+ this.author = author;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Book)) {
+ return false;
+ }
+
+ Book book = (Book) o;
+
+ if (!Objects.equals(bookId, book.bookId)) {
+ return false;
+ }
+ if (!Objects.equals(title, book.title)) {
+ return false;
+ }
+ return Objects.equals(author, book.author);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = bookId != null ? bookId.hashCode() : 0;
+ result = 31 * result + (title != null ? title.hashCode() : 0);
+ result = 31 * result + (author != null ? author.hashCode() : 0);
+ return result;
+ }
+
+ public Integer getBookId() {
+ return bookId;
+ }
+
+ public void setBookId(Integer bookId) {
+ this.bookId = bookId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java
new file mode 100644
index 0000000000..f60a3cde5a
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java
@@ -0,0 +1,24 @@
+package com.ossez.jackson.tocollection;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JsonToCollectionUtil {
+
+ private JsonToCollectionUtil(){}
+
+ public static List jsonArrayToList(String json, Class elementClass) throws IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
+ return objectMapper.readValue(json, listType);
+ }
+
+ public static List jsonArrayToList2(String json, Class elementClass) throws IOException {
+ return new ObjectMapper().readValue(json, new TypeReference
>() {});
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java
new file mode 100644
index 0000000000..da3c3fa590
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java
@@ -0,0 +1,5 @@
+package com.ossez.jackson.xmlToJson;
+
+public enum Color {
+ PINK, BLUE, YELLOW, RED;
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java
new file mode 100644
index 0000000000..8963c52c27
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java
@@ -0,0 +1,42 @@
+package com.ossez.jackson.xmlToJson;
+
+public class Flower {
+
+ private String name;
+
+ private Color color;
+
+ private Integer petals;
+
+ public Flower() { }
+
+ public Flower(String name, Color color, Integer petals) {
+ this.name = name;
+ this.color = color;
+ this.petals = petals;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ public Integer getPetals() {
+ return petals;
+ }
+
+ public void setPetals(Integer petals) {
+ this.petals = petals;
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java
new file mode 100644
index 0000000000..b9739544e9
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java
@@ -0,0 +1,68 @@
+package com.ossez.jackson.yaml;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Order {
+ private String orderNo;
+ private LocalDate date;
+ private String customerName;
+ private List orderLines;
+
+ public Order() {
+
+ }
+
+ public Order(String orderNo, LocalDate date, String customerName, List orderLines) {
+ super();
+ this.orderNo = orderNo;
+ this.date = date;
+ this.customerName = customerName;
+ this.orderLines = orderLines;
+ }
+
+ public String getOrderNo() {
+ return orderNo;
+ }
+
+ public void setOrderNo(String orderNo) {
+ this.orderNo = orderNo;
+ }
+
+ public LocalDate getDate() {
+ return date;
+ }
+
+ public void setDate(LocalDate date) {
+ this.date = date;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public List getOrderLines() {
+ if (orderLines == null) {
+ orderLines = new ArrayList<>();
+ }
+ return orderLines;
+ }
+
+ public void setOrderLines(List orderLines) {
+ if (orderLines == null) {
+ orderLines = new ArrayList<>();
+ }
+ this.orderLines = orderLines;
+ }
+
+ @Override
+ public String toString() {
+ return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]";
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java
new file mode 100644
index 0000000000..c30a5fd120
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java
@@ -0,0 +1,49 @@
+package com.ossez.jackson.yaml;
+
+import java.math.BigDecimal;
+
+public class OrderLine {
+ private String item;
+ private int quantity;
+ private BigDecimal unitPrice;
+
+ public OrderLine() {
+
+ }
+
+ public OrderLine(String item, int quantity, BigDecimal unitPrice) {
+ super();
+ this.item = item;
+ this.quantity = quantity;
+ this.unitPrice = unitPrice;
+ }
+
+ public String getItem() {
+ return item;
+ }
+
+ public void setItem(String item) {
+ this.item = item;
+ }
+
+ public int getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
+
+ public BigDecimal getUnitPrice() {
+ return unitPrice;
+ }
+
+ public void setUnitPrice(BigDecimal unitPrice) {
+ this.unitPrice = unitPrice;
+ }
+
+ @Override
+ public String toString() {
+ return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]";
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv
new file mode 100644
index 0000000000..e15e12f2bf
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv
@@ -0,0 +1,3 @@
+item,quantity,unitPrice
+"No. 9 Sprockets",12,1.23
+"Widget (10mm)",4,3.45
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json
new file mode 100644
index 0000000000..64f18e1673
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json
@@ -0,0 +1,9 @@
+[ {
+ "item" : "No. 9 Sprockets",
+ "quantity" : 12,
+ "unitPrice" : 1.23
+}, {
+ "item" : "Widget (10mm)",
+ "quantity" : 4,
+ "unitPrice" : 3.45
+} ]
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json
new file mode 100644
index 0000000000..6daf426736
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json
@@ -0,0 +1,13 @@
+[ {
+ "bookId" : 1,
+ "title" : "A Song of Ice and Fire",
+ "author" : "George R. R. Martin"
+}, {
+ "bookId" : 2,
+ "title" : "The Hitchhiker's Guide to the Galaxy",
+ "author" : "Douglas Adams"
+}, {
+ "bookId" : 3,
+ "title" : "Hackers And Painters",
+ "author" : "Paul Graham"
+} ]
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml
new file mode 100644
index 0000000000..b2f951315b
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml
@@ -0,0 +1,17 @@
+
+ -
+ 1
+ A Song of Ice and Fire
+ George R. R. Martin
+
+ -
+ 2
+ The Hitchhiker's Guide to the Galaxy
+ Douglas Adams
+
+ -
+ 3
+ Hackers And Painters
+ Paul Graham
+
+
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java
new file mode 100644
index 0000000000..31f49da723
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java
@@ -0,0 +1,65 @@
+package com.ossez.jackson.csv;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.google.common.io.Files;
+
+public class CsvUnitTest {
+
+ private File csvFromJson;
+ private File jsonFromCsv;
+ private File formattedCsvFromJson;
+
+ @Before
+ public void setup() {
+ csvFromJson = new File("src/main/resources/csv/csvFromJson.csv");
+ jsonFromCsv = new File("src/main/resources/csv/jsonFromCsv.json");
+ formattedCsvFromJson = new File("src/main/resources/csv/formattedCsvFromJson.csv");
+ }
+
+ @After
+ public void cleanup() {
+ csvFromJson.deleteOnExit();
+ jsonFromCsv.deleteOnExit();
+ formattedCsvFromJson.deleteOnExit();
+ }
+
+ @Test
+ public void givenJsonInput_thenWriteCsv() throws JsonParseException, JsonMappingException, IOException {
+ JsonCsvConverter.JsonToCsv(new File("src/main/resources/csv/orderLines.json"), csvFromJson);
+
+ assertEquals(readFile(csvFromJson.getAbsolutePath()), readFile("src/test/resources/csv/expectedCsvFromJson.csv"));
+ }
+
+ @Test
+ public void givenCsvInput_thenWritesJson() throws JsonParseException, JsonMappingException, IOException {
+ JsonCsvConverter.csvToJson(new File("src/main/resources/csv/orderLines.csv"), jsonFromCsv);
+
+ assertEquals(readFile(jsonFromCsv.getAbsolutePath()), readFile("src/test/resources/csv/expectedJsonFromCsv.json"));
+
+ }
+
+ @Test
+ public void givenJsonInput_thenWriteFormattedCsvOutput() throws JsonParseException, JsonMappingException, IOException {
+ JsonCsvConverter.JsonToFormattedCsv(new File("src/main/resources/csv/orderLines.json"), formattedCsvFromJson);
+
+ assertEquals(readFile(formattedCsvFromJson.getAbsolutePath()), readFile("src/test/resources/csv/expectedFormattedCsvFromJson.csv"));
+
+ }
+
+ private List readFile(String filename) throws IOException {
+ return Files.readLines(new File(filename), Charset.forName("utf-8"));
+ }
+
+};
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java
new file mode 100644
index 0000000000..f037bb398f
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java
@@ -0,0 +1,69 @@
+package com.ossez.jackson.dynamicobject;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.util.Scanner;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class DynamicObjectDeserializationUnitTest {
+
+ private ObjectMapper objectMapper;
+
+ @BeforeEach
+ void setup() {
+ objectMapper = new ObjectMapper();
+ }
+
+ private String readResource(String path) {
+ try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+ @Test
+ void givenJsonString_whenParsingToJsonNode_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException {
+ // given
+ String json = readResource("/deserialize-dynamic-object/embedded.json");
+
+ // when
+ ProductJsonNode product = objectMapper.readValue(json, ProductJsonNode.class);
+
+ // then
+ assertThat(product.getName()).isEqualTo("Pear yPhone 72");
+ assertThat(product.getDetails().get("audioConnector").asText()).isEqualTo("none");
+ }
+
+ @Test
+ void givenJsonString_whenParsingToMap_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException {
+ // given
+ String json = readResource("/deserialize-dynamic-object/embedded.json");
+
+ // when
+ ProductMap product = objectMapper.readValue(json, ProductMap.class);
+
+ // then
+ assertThat(product.getName()).isEqualTo("Pear yPhone 72");
+ assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");
+ }
+
+ @Test
+ void givenJsonString_whenParsingWithJsonAnySetter_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException {
+ // given
+ String json = readResource("/deserialize-dynamic-object/flat.json");
+
+ // when
+ Product product = objectMapper.readValue(json, Product.class);
+
+ // then
+ assertThat(product.getName()).isEqualTo("Pear yPhone 72");
+ assertThat(product.getDetails().get("audioConnector")).isEqualTo("none");
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java
new file mode 100644
index 0000000000..fa8659bacd
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java
@@ -0,0 +1,37 @@
+package com.ossez.jackson.multiplefields;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class MapMultipleFieldsToSingleFieldUnitTest {
+
+ @Test
+ public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception {
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ Weather weather = mapper.readValue("{" +
+ "\"location\": \"London\"," +
+ "\"temp\": 15," +
+ "\"weather\": \"Cloudy\"" +
+ "}", Weather.class);
+
+ assertEquals("London", weather.getLocation());
+ assertEquals("Cloudy", weather.getOutlook());
+ assertEquals(15, weather.getTemp());
+
+ weather = mapper.readValue("{" +
+ "\"place\": \"Lisbon\"," +
+ "\"temperature\": 35," +
+ "\"outlook\": \"Sunny\"" +
+ "}", Weather.class);
+
+ assertEquals("Lisbon", weather.getLocation());
+ assertEquals("Sunny", weather.getOutlook());
+ assertEquals(35, weather.getTemp());
+
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java
new file mode 100644
index 0000000000..4e987a9d7c
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java
@@ -0,0 +1,118 @@
+package com.ossez.jackson.streaming;
+
+import com.fasterxml.jackson.core.*;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+
+public class StreamingAPIUnitTest {
+
+ @Test
+ public void givenJsonGenerator_whenAppendJsonToIt_thenGenerateJson() throws IOException {
+ // given
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ JsonFactory jfactory = new JsonFactory();
+ JsonGenerator jGenerator = jfactory.createGenerator(stream, JsonEncoding.UTF8);
+
+ // when
+ jGenerator.writeStartObject();
+ jGenerator.writeStringField("name", "Tom");
+ jGenerator.writeNumberField("age", 25);
+ jGenerator.writeFieldName("address");
+ jGenerator.writeStartArray();
+ jGenerator.writeString("Poland");
+ jGenerator.writeString("5th avenue");
+ jGenerator.writeEndArray();
+ jGenerator.writeEndObject();
+ jGenerator.close();
+
+ // then
+ String json = new String(stream.toByteArray(), "UTF-8");
+ assertEquals(json, "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}");
+ }
+
+ @Test
+ public void givenJson_whenReadItUsingStreamAPI_thenShouldCreateProperJsonObject() throws IOException {
+ // given
+ String json = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
+ JsonFactory jfactory = new JsonFactory();
+ JsonParser jParser = jfactory.createParser(json);
+
+ String parsedName = null;
+ Integer parsedAge = null;
+ List addresses = new LinkedList<>();
+
+ // when
+ while (jParser.nextToken() != JsonToken.END_OBJECT) {
+
+ String fieldname = jParser.getCurrentName();
+ if ("name".equals(fieldname)) {
+ jParser.nextToken();
+ parsedName = jParser.getText();
+
+ }
+
+ if ("age".equals(fieldname)) {
+ jParser.nextToken();
+ parsedAge = jParser.getIntValue();
+
+ }
+
+ if ("address".equals(fieldname)) {
+ jParser.nextToken();
+
+ while (jParser.nextToken() != JsonToken.END_ARRAY) {
+ addresses.add(jParser.getText());
+ }
+ }
+
+ }
+ jParser.close();
+
+ // then
+ assertEquals(parsedName, "Tom");
+ assertEquals(parsedAge, (Integer) 25);
+ assertEquals(addresses, Arrays.asList("Poland", "5th avenue"));
+
+ }
+
+ @Test
+ public void givenJson_whenWantToExtractPartOfIt_thenShouldExtractOnlyNeededFieldWithoutGoingThroughWholeJSON() throws IOException {
+ // given
+ String json = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
+ JsonFactory jfactory = new JsonFactory();
+ JsonParser jParser = jfactory.createParser(json);
+
+ String parsedName = null;
+ Integer parsedAge = null;
+ List addresses = new LinkedList<>();
+
+ // when
+ while (jParser.nextToken() != JsonToken.END_OBJECT) {
+
+ String fieldname = jParser.getCurrentName();
+
+ if ("age".equals(fieldname)) {
+ jParser.nextToken();
+ parsedAge = jParser.getIntValue();
+ return;
+ }
+
+ }
+ jParser.close();
+
+ // then
+ assertNull(parsedName);
+ assertEquals(parsedAge, (Integer) 25);
+ assertTrue(addresses.isEmpty());
+
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java
new file mode 100644
index 0000000000..bf340fbb74
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java
@@ -0,0 +1,130 @@
+package com.ossez.jackson.tocollection;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+public class DeserializeToJavaCollectionUnitTest {
+ private ObjectMapper objectMapper;
+ private XmlMapper xmlMapper;
+ private List expectedBookList;
+
+
+ @BeforeEach
+ void setup() {
+ objectMapper = new ObjectMapper();
+ xmlMapper = new XmlMapper();
+ expectedBookList = Lists.newArrayList(
+ new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
+ new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
+ new Book(3, "Hackers And Painters", "Paul Graham"));
+ }
+
+ private String readFile(String path) {
+ try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+ /*====================
+ * JSON tests
+ *====================
+ */
+ @Test
+ void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ List bookList = objectMapper.readValue(jsonString, ArrayList.class);
+ assertThat(bookList).size().isEqualTo(3);
+ assertThatExceptionOfType(ClassCastException.class)
+ .isThrownBy(() -> bookList.get(0).getBookId())
+ .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+ }
+
+ @Test
+ void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ List bookList = objectMapper.readValue(jsonString, new TypeReference>() {});
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class);
+ List bookList = objectMapper.readValue(jsonString, listType);
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ JsonNode jsonNode = objectMapper.readTree(jsonString);
+ List bookList = objectMapper.convertValue(jsonNode, new TypeReference>() {});
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ JsonNode jsonNode = objectMapper.readTree(jsonString);
+ List bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ /*====================
+ * XML tests
+ *====================
+ */
+ @Test
+ void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
+ String xml = readFile("/to-java-collection/books.xml");
+ List bookList = xmlMapper.readValue(xml, ArrayList.class);
+ assertThat(bookList).size().isEqualTo(3);
+ assertThatExceptionOfType(ClassCastException.class)
+ .isThrownBy(() -> bookList.get(0).getBookId())
+ .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+ }
+
+ @Test
+ void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
+ String xml = readFile("/to-java-collection/books.xml");
+ List bookList = xmlMapper.readValue(xml, new TypeReference>() {});
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
+ String xml = readFile("/to-java-collection/books.xml");
+ List node = xmlMapper.readValue(xml, List.class);
+ List bookList = xmlMapper.convertValue(node, new TypeReference>() {});
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
+ String xml = readFile("/to-java-collection/books.xml");
+ List node = xmlMapper.readValue(xml, List.class);
+ List bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java
new file mode 100644
index 0000000000..1cd14f3504
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java
@@ -0,0 +1,51 @@
+package com.ossez.jackson.tocollection;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Scanner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+class JsonToCollectionUtilUnitTest {
+
+ private List expectedBookList;
+
+
+ @BeforeEach
+ void setup() {
+ expectedBookList = Lists.newArrayList(
+ new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
+ new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
+ new Book(3, "Hackers And Painters", "Paul Graham"));
+ }
+
+ private String readFile(String path) {
+ try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+ @Test
+ void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ List bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class);
+ assertThat(bookList.get(0)).isInstanceOf(Book.class);
+ assertThat(bookList).isEqualTo(expectedBookList);
+ }
+
+ @Test
+ void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException {
+ String jsonString = readFile("/to-java-collection/books.json");
+ List bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class);
+ assertThat(bookList).size().isEqualTo(3);
+ assertThatExceptionOfType(ClassCastException.class)
+ .isThrownBy(() -> bookList.get(0).getBookId())
+ .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java
new file mode 100644
index 0000000000..170b1db71e
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java
@@ -0,0 +1,43 @@
+package com.ossez.jackson.xmlToJson;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+public class XmlToJsonUnitTest {
+
+ @Test
+ public void givenAnXML_whenUseDataBidingToConvertToJSON_thenReturnDataOK() throws IOException{
+ String flowerXML = "PoppyRED9";
+
+ XmlMapper xmlMapper = new XmlMapper();
+ Flower poppy = xmlMapper.readValue(flowerXML, Flower.class);
+
+ assertEquals(poppy.getName(), "Poppy");
+ assertEquals(poppy.getColor(), Color.RED);
+ assertEquals(poppy.getPetals(), new Integer(9));
+
+ ObjectMapper mapper = new ObjectMapper();
+ String json = mapper.writeValueAsString(poppy);
+
+ assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":9}");
+ }
+
+ @Test
+ public void givenAnXML_whenUseATreeConvertToJSON_thenReturnDataOK() throws IOException {
+ String flowerXML = "PoppyRED9";
+
+ XmlMapper xmlMapper = new XmlMapper();
+ JsonNode node = xmlMapper.readTree(flowerXML.getBytes());
+
+ ObjectMapper jsonMapper = new ObjectMapper();
+ String json = jsonMapper.writeValueAsString(node);
+
+ assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":\"9\"}");
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java
new file mode 100644
index 0000000000..92a008d17e
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java
@@ -0,0 +1,69 @@
+package com.ossez.jackson.yaml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
+
+public class YamlUnitTest {
+ private ObjectMapper mapper;
+ private File orderOutput;
+
+ @Before
+ public void setup() {
+ mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
+ mapper.findAndRegisterModules();
+ mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ orderOutput = new File("src/test/resources/yaml/orderOutput.yaml");
+ }
+
+ @After
+ public void cleanup() {
+ orderOutput.deleteOnExit();
+ }
+
+ @Test
+ public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException {
+ Order order = mapper.readValue(new File("src/test/resources/yaml/orderInput.yaml"), Order.class);
+ assertEquals("A001", order.getOrderNo());
+ assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate());
+ assertEquals("Customer, Joe", order.getCustomerName());
+ assertEquals(2, order.getOrderLines()
+ .size());
+ }
+
+ @Test
+ public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException {
+ List lines = new ArrayList<>();
+ lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP)));
+ lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP)));
+ Order order = new Order(
+ "B-9910",
+ LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE),
+ "Customer, Jane",
+ lines);
+ mapper.writeValue(orderOutput, order);
+
+ File outputYaml = new File(orderOutput.getAbsolutePath());
+ assertTrue(outputYaml.exists());
+ }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv
new file mode 100644
index 0000000000..e15e12f2bf
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv
@@ -0,0 +1,3 @@
+item,quantity,unitPrice
+"No. 9 Sprockets",12,1.23
+"Widget (10mm)",4,3.45
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv
new file mode 100644
index 0000000000..5a60ba602a
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv
@@ -0,0 +1,3 @@
+count,name
+12,"No. 9 Sprockets"
+4,"Widget (10mm)"
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json
new file mode 100644
index 0000000000..64f18e1673
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json
@@ -0,0 +1,9 @@
+[ {
+ "item" : "No. 9 Sprockets",
+ "quantity" : 12,
+ "unitPrice" : 1.23
+}, {
+ "item" : "Widget (10mm)",
+ "quantity" : 4,
+ "unitPrice" : 3.45
+} ]
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json
new file mode 100644
index 0000000000..e4f11f7f1f
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json
@@ -0,0 +1,8 @@
+{
+ "name": "Pear yPhone 72",
+ "category": "cellphone",
+ "details": {
+ "displayAspectRatio": "97:3",
+ "audioConnector": "none"
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json
new file mode 100644
index 0000000000..799ea9339d
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json
@@ -0,0 +1,6 @@
+{
+ "name": "Pear yPhone 72",
+ "category": "cellphone",
+ "displayAspectRatio": "97:3",
+ "audioConnector": "none"
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml b/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml
new file mode 100644
index 0000000000..0aaa6186a2
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml
@@ -0,0 +1,11 @@
+orderNo: A001
+date: 2019-04-17
+customerName: Customer, Joe
+orderLines:
+ - item: No. 9 Sprockets
+ quantity: 12
+ unitPrice: 1.23
+ - item: Widget (10mm)
+ quantity: 4
+ unitPrice: 3.45
+
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/README.md b/jackson-modules/jackson-conversions/README.md
new file mode 100644
index 0000000000..25e299800a
--- /dev/null
+++ b/jackson-modules/jackson-conversions/README.md
@@ -0,0 +1,16 @@
+## Jackson 转换
+
+这个模块主要是针对 Jackson 转换(Jackson Conversions) 有关的文章。
+
+### Relevant Articles:
+- [Jackson – Unmarshall to Collection/Array](https://www.baeldung.com/jackson-collection-array)
+- [Jackson Date](https://www.baeldung.com/jackson-serialize-dates)
+- [Jackson – Working with Maps and Nulls](https://www.baeldung.com/jackson-map-null-values-or-null-key)
+- [Jackson – Decide What Fields Get Serialized/Deserialized](https://www.baeldung.com/jackson-field-serializable-deserializable-or-not)
+- [XML Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-xml-serialization-and-deserialization)
+- [Map Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-map)
+- [How to Serialize and Deserialize Enums with Jackson](https://www.baeldung.com/jackson-serialize-enums)
+- [使用 Jackson – 将字符串转换为 JsonNode 对象](https://www.ossez.com/t/jackson-jsonnode/13724)
+- [Mapping Nested Values with Jackson](https://www.baeldung.com/jackson-nested-values)
+- [Deserialize Immutable Objects with Jackson](https://www.baeldung.com/jackson-deserialize-immutable-objects)
+- More articles: [[next -->]](../jackson-conversions-2)
diff --git a/jackson-modules/jackson-conversions/pom.xml b/jackson-modules/jackson-conversions/pom.xml
new file mode 100644
index 0000000000..f11e2b35fd
--- /dev/null
+++ b/jackson-modules/jackson-conversions/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+ jackson-conversions
+ 0.0.1-SNAPSHOT
+ jackson-conversions
+
+
+ com.ossez
+ jackson-modules
+ 0.0.2-SNAPSHOT
+
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-joda
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
+
+
+ jackson-conversions
+
+
+ src/main/resources
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java
new file mode 100644
index 0000000000..6d0fe42cde
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java
@@ -0,0 +1,36 @@
+package com.ossez.jackson.date;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class CustomDateDeserializer extends StdDeserializer {
+
+ private static final long serialVersionUID = -5451717385630622729L;
+ private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ public CustomDateDeserializer() {
+ this(null);
+ }
+
+ public CustomDateDeserializer(final Class> vc) {
+ super(vc);
+ }
+
+ @Override
+ public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
+ final String date = jsonparser.getText();
+ try {
+ return formatter.parse(date);
+ } catch (final ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java
new file mode 100644
index 0000000000..db5d68c746
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.date;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomDateSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -2894356342227378312L;
+ private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ public CustomDateSerializer() {
+ this(null);
+ }
+
+ public CustomDateSerializer(final Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.format(value));
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java
new file mode 100644
index 0000000000..9d72a89292
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java
@@ -0,0 +1,32 @@
+package com.ossez.jackson.date;
+
+import java.io.IOException;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomDateTimeSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -3927232057990121460L;
+
+ public CustomDateTimeSerializer() {
+ this(null);
+ }
+
+ public CustomDateTimeSerializer(final Class t) {
+ super(t);
+ }
+
+ private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
+
+ @Override
+ public void serialize(final DateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.print(value));
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java
new file mode 100644
index 0000000000..e6fea554d3
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.date;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomLocalDateTimeSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -7449444168934819290L;
+ private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
+ public CustomLocalDateTimeSerializer() {
+ this(null);
+ }
+
+ public CustomLocalDateTimeSerializer(final Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.format(value));
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java
new file mode 100644
index 0000000000..7762d5907b
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java
@@ -0,0 +1,25 @@
+package com.ossez.jackson.date;
+
+import java.util.Date;
+
+public class Event {
+ public String name;
+ public Date eventDate;
+
+ public Event() {
+ super();
+ }
+
+ public Event(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java
new file mode 100644
index 0000000000..fe73f551c7
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+public class EventWithFormat {
+ public String name;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
+ public Date eventDate;
+
+ public EventWithFormat() {
+ super();
+ }
+
+ public EventWithFormat(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java
new file mode 100644
index 0000000000..b9e0a8672f
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.date;
+
+import org.joda.time.DateTime;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithJodaTime {
+ public String name;
+
+ @JsonSerialize(using = CustomDateTimeSerializer.class)
+ public DateTime eventDate;
+
+ public EventWithJodaTime() {
+ super();
+ }
+
+ public EventWithJodaTime(final String name, final DateTime eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public DateTime getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java
new file mode 100644
index 0000000000..1562987b5b
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java
@@ -0,0 +1,33 @@
+package com.ossez.jackson.date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+
+import java.time.LocalDate;
+
+public class EventWithLocalDate {
+ public String name;
+
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ @JsonSerialize(using = LocalDateSerializer.class)
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
+ public LocalDate eventDate;
+
+ public EventWithLocalDate() {}
+
+ public EventWithLocalDate(final String name, final LocalDate eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public LocalDate getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java
new file mode 100644
index 0000000000..f5d048fa93
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.date;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithLocalDateTime {
+ public String name;
+
+ @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
+ public LocalDateTime eventDate;
+
+ public EventWithLocalDateTime() {
+ super();
+ }
+
+ public EventWithLocalDateTime(final String name, final LocalDateTime eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public LocalDateTime getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java
new file mode 100644
index 0000000000..595bcb8f76
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java
@@ -0,0 +1,31 @@
+package com.ossez.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithSerializer {
+ public String name;
+
+ @JsonDeserialize(using = CustomDateDeserializer.class)
+ @JsonSerialize(using = CustomDateSerializer.class)
+ public Date eventDate;
+
+ public EventWithSerializer() {
+ super();
+ }
+
+ public EventWithSerializer(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java
new file mode 100644
index 0000000000..c86868de6e
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java
@@ -0,0 +1,15 @@
+package com.ossez.jackson.enums.deserialization;
+
+public class City {
+
+ private Distance distance;
+
+ public Distance getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Distance distance) {
+ this.distance = distance;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java
new file mode 100644
index 0000000000..96829dc3c9
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java
@@ -0,0 +1,31 @@
+package com.ossez.jackson.enums.deserialization;
+
+public enum Distance {
+
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public void setMeters(double meters) {
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+}
+
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java
new file mode 100644
index 0000000000..42425f8c07
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java
@@ -0,0 +1,15 @@
+package com.ossez.jackson.enums.deserialization.customdeserializer;
+
+public class City {
+
+ private Distance distance;
+
+ public Distance getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Distance distance) {
+ this.distance = distance;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java
new file mode 100644
index 0000000000..bb26606741
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java
@@ -0,0 +1,42 @@
+package com.ossez.jackson.enums.deserialization.customdeserializer;
+
+import java.io.IOException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class CustomEnumDeserializer extends StdDeserializer {
+
+ private static final long serialVersionUID = -1166032307856492833L;
+
+ public CustomEnumDeserializer() {
+ this(null);
+ }
+
+ public CustomEnumDeserializer(Class> c) {
+ super(c);
+ }
+
+ @Override
+ public Distance deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+
+ JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+
+ String unit = node.get("unit").asText();
+ double meters = node.get("meters").asDouble();
+
+ for (Distance distance : Distance.values()) {
+
+ if (distance.getUnit().equals(unit) &&
+ Double.compare(distance.getMeters(), meters) == 0) {
+
+ return distance;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java
new file mode 100644
index 0000000000..b6053f01d8
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java
@@ -0,0 +1,33 @@
+package com.ossez.jackson.enums.deserialization.customdeserializer;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+@JsonDeserialize(using = CustomEnumDeserializer.class)
+public enum Distance {
+
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public void setMeters(double meters) {
+ this.meters = meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java
new file mode 100644
index 0000000000..734af4e548
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java
@@ -0,0 +1,15 @@
+package com.ossez.jackson.enums.deserialization.jsoncreator;
+
+public class City {
+
+ private Distance distance;
+
+ public Distance getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Distance distance) {
+ this.distance = distance;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java
new file mode 100644
index 0000000000..1c6bdfaad8
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java
@@ -0,0 +1,48 @@
+package com.ossez.jackson.enums.deserialization.jsoncreator;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public enum Distance {
+
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public void setMeters(double meters) {
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ @JsonCreator
+ public static Distance forValues(@JsonProperty("unit") String unit, @JsonProperty("meters") double meters) {
+
+ for (Distance distance : Distance.values()) {
+ if (distance.unit.equals(unit) && Double.compare(distance.meters, meters) == 0) {
+
+ return distance;
+ }
+ }
+
+ return null;
+
+ }
+}
+
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java
new file mode 100644
index 0000000000..8d3ce1b326
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java
@@ -0,0 +1,15 @@
+package com.ossez.jackson.enums.deserialization.jsonproperty;
+
+public class City {
+
+ private Distance distance;
+
+ public Distance getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Distance distance) {
+ this.distance = distance;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java
new file mode 100644
index 0000000000..656a3dceee
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java
@@ -0,0 +1,51 @@
+package com.ossez.jackson.enums.deserialization.jsonproperty;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public enum Distance {
+
+ @JsonProperty("distance-in-km")
+ KILOMETER("km", 1000),
+
+ @JsonProperty("distance-in-miles")
+ MILE("miles", 1609.34),
+
+ @JsonProperty("distance-in-meters")
+ METER("meters", 1),
+
+ @JsonProperty("distance-in-inches")
+ INCH("inches", 0.0254),
+
+ @JsonProperty("distance-in-cm")
+ CENTIMETER("cm", 0.01),
+
+ @JsonProperty("distance-in-mm")
+ MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public void setMeters(double meters) {
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
+
+
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java
new file mode 100644
index 0000000000..bfe7f3c6e9
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java
@@ -0,0 +1,15 @@
+package com.ossez.jackson.enums.deserialization.jsonvalue;
+
+public class City {
+
+ private Distance distance;
+
+ public Distance getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Distance distance) {
+ this.distance = distance;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java
new file mode 100644
index 0000000000..530ddf9047
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java
@@ -0,0 +1,35 @@
+package com.ossez.jackson.enums.deserialization.jsonvalue;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum Distance {
+
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public void setMeters(double meters) {
+ this.meters = meters;
+ }
+
+ @JsonValue
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
+
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java
new file mode 100644
index 0000000000..18ef758dfc
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java
@@ -0,0 +1,53 @@
+package com.ossez.jackson.enums.serialization;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * Use @JsonFormat to handle representation of Enum as JSON (available since Jackson 2.1.2)
+ * Use @JsonSerialize to configure a custom Jackson serializer
+ */
+// @JsonFormat(shape = JsonFormat.Shape.OBJECT)
+@JsonSerialize(using = DistanceSerializer.class)
+public enum Distance {
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private final double meters;
+
+ private Distance(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ /**
+ * Use @JsonValue to control marshalling output for an enum
+ */
+ // @JsonValue
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ /**
+ * Usage example: Distance.MILE.convertFromMeters(1205.5);
+ */
+ public double convertFromMeters(double distanceInMeters) {
+ return distanceInMeters / meters;
+
+ }
+
+ /**
+ * Usage example: Distance.MILE.convertToMeters(0.5);
+ */
+ public double convertToMeters(double distanceInMeters) {
+ return distanceInMeters * meters;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java
new file mode 100644
index 0000000000..8fc9458daf
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java
@@ -0,0 +1,32 @@
+package com.ossez.jackson.enums.serialization;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class DistanceSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = 1376504304439963619L;
+
+ public DistanceSerializer() {
+ super(Distance.class);
+ }
+
+ public DistanceSerializer(Class t) {
+ super(t);
+ }
+
+ public void serialize(Distance distance, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
+ generator.writeStartObject();
+ generator.writeFieldName("name");
+ generator.writeString(distance.name());
+ generator.writeFieldName("unit");
+ generator.writeString(distance.getUnit());
+ generator.writeFieldName("meters");
+ generator.writeNumber(distance.getMeters());
+ generator.writeEndObject();
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java
new file mode 100644
index 0000000000..a282e9e35f
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java
@@ -0,0 +1,26 @@
+package com.ossez.jackson.enums.withEnum;
+
+public enum DistanceEnumSimple {
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private final double meters;
+
+ private DistanceEnumSimple(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java
new file mode 100644
index 0000000000..c3d0050f31
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.enums.withEnum;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum DistanceEnumWithJsonFormat {
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private final double meters;
+
+ private DistanceEnumWithJsonFormat(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java
new file mode 100644
index 0000000000..a94cdde511
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.enums.withEnum;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum DistanceEnumWithValue {
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private final double meters;
+
+ private DistanceEnumWithValue(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ @JsonValue
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java
new file mode 100644
index 0000000000..9895d03262
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java
@@ -0,0 +1,59 @@
+package com.ossez.jackson.enums.withEnum;
+
+import com.ossez.jackson.enums.serialization.Distance;
+
+public class MyDtoWithEnumCustom {
+
+ private String stringValue;
+ private int intValue;
+ private boolean booleanValue;
+ private Distance type;
+
+ public MyDtoWithEnumCustom() {
+ super();
+ }
+
+ public MyDtoWithEnumCustom(final String stringValue, final int intValue, final boolean booleanValue, final Distance type) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ this.type = type;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+ public Distance getType() {
+ return type;
+ }
+
+ public void setType(final Distance type) {
+ this.type = type;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java
new file mode 100644
index 0000000000..c58b20b87d
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java
@@ -0,0 +1,57 @@
+package com.ossez.jackson.enums.withEnum;
+
+public class MyDtoWithEnumJsonFormat {
+
+ private String stringValue;
+ private int intValue;
+ private boolean booleanValue;
+ private DistanceEnumWithJsonFormat distanceType;
+
+ public MyDtoWithEnumJsonFormat() {
+ super();
+ }
+
+ public MyDtoWithEnumJsonFormat(final String stringValue, final int intValue, final boolean booleanValue, final DistanceEnumWithJsonFormat type) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ this.distanceType = type;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+ public DistanceEnumWithJsonFormat getDistanceType() {
+ return distanceType;
+ }
+
+ public void setDistanceType(final DistanceEnumWithJsonFormat type) {
+ this.distanceType = type;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java
new file mode 100644
index 0000000000..a4583c8b44
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java
@@ -0,0 +1,47 @@
+package com.ossez.jackson.field;
+
+public class MyDto {
+
+ private String stringValue;
+ private int intValue;
+ private boolean booleanValue;
+
+ public MyDto() {
+ super();
+ }
+
+ public MyDto(final String stringValue, final int intValue, final boolean booleanValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean getBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java
new file mode 100644
index 0000000000..7c0604990f
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java
@@ -0,0 +1,23 @@
+package com.ossez.jackson.field;
+
+public class MyDtoAccessLevel {
+
+ private String stringValue;
+ int intValue;
+ protected float floatValue;
+ public boolean booleanValue;
+
+ public MyDtoAccessLevel() {
+ super();
+ }
+
+ public MyDtoAccessLevel(final String stringValue, final int intValue, final float floatValue, final boolean booleanValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.floatValue = floatValue;
+ this.booleanValue = booleanValue;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java
new file mode 100644
index 0000000000..7d60251959
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java
@@ -0,0 +1,25 @@
+package com.ossez.jackson.field;
+
+public class MyDtoWithGetter {
+
+ private String stringValue;
+ private int intValue;
+
+ public MyDtoWithGetter() {
+ super();
+ }
+
+ public MyDtoWithGetter(final String stringValue, final int intValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java
new file mode 100644
index 0000000000..f32c5d2151
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java
@@ -0,0 +1,29 @@
+package com.ossez.jackson.field;
+
+public class MyDtoWithSetter {
+
+ private int intValue;
+ public boolean booleanValue;
+
+ public MyDtoWithSetter() {
+ super();
+ }
+
+ public MyDtoWithSetter(final int intValue, final boolean booleanValue) {
+ super();
+
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ }
+
+ // API
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public int accessIntValue() {
+ return intValue;
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java
new file mode 100644
index 0000000000..46f44161cd
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java
@@ -0,0 +1,24 @@
+package com.ossez.jackson.immutable;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Employee {
+
+ private final long id;
+ private final String name;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Employee(@JsonProperty("id") long id, @JsonProperty("name") String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java
new file mode 100644
index 0000000000..9df9f8c808
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java
@@ -0,0 +1,44 @@
+package com.ossez.jackson.immutable;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+
+@JsonDeserialize(builder = Person.Builder.class)
+public class Person {
+
+ private final String name;
+ private final Integer age;
+
+ private Person(String name, Integer age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ @JsonPOJOBuilder
+ static class Builder {
+ String name;
+ Integer age;
+
+ Builder withName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ Builder withAge(Integer age) {
+ this.age = age;
+ return this;
+ }
+
+ Person build() {
+ return new Person(name, age);
+ }
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java
new file mode 100644
index 0000000000..09a9818630
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java
@@ -0,0 +1,23 @@
+package com.ossez.jackson.map;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+public class ClassWithAMap {
+
+ @JsonProperty("map")
+ @JsonDeserialize(keyUsing = MyPairDeserializer.class)
+ private final Map map;
+
+ @JsonCreator
+ public ClassWithAMap(Map map) {
+ this.map = map;
+ }
+
+ public Map getMap() {
+ return map;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java
new file mode 100644
index 0000000000..4578aea4f2
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java
@@ -0,0 +1,80 @@
+package com.ossez.jackson.map;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public class MyPair {
+
+ private String first;
+ private String second;
+
+ public MyPair(String first, String second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public MyPair(String both) {
+ String[] pairs = both.split("and");
+ this.first = pairs[0].trim();
+ this.second = pairs[1].trim();
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return first + " and " + second;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((first == null) ? 0 : first.hashCode());
+ result = prime * result + ((second == null) ? 0 : second.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof MyPair)) {
+ return false;
+ }
+ MyPair other = (MyPair) obj;
+ if (first == null) {
+ if (other.first != null) {
+ return false;
+ }
+ } else if (!first.equals(other.first)) {
+ return false;
+ }
+ if (second == null) {
+ if (other.second != null) {
+ return false;
+ }
+ } else if (!second.equals(other.second)) {
+ return false;
+ }
+ return true;
+ }
+
+ public String getFirst() {
+ return first;
+ }
+
+ public void setFirst(String first) {
+ this.first = first;
+ }
+
+ public String getSecond() {
+ return second;
+ }
+
+ public void setSecond(String second) {
+ this.second = second;
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java
new file mode 100644
index 0000000000..5feb836b11
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java
@@ -0,0 +1,16 @@
+package com.ossez.jackson.map;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.KeyDeserializer;
+
+public class MyPairDeserializer extends KeyDeserializer {
+
+ @Override
+ public MyPair deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+
+ return new MyPair(key);
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java
new file mode 100644
index 0000000000..4fe480ff0d
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java
@@ -0,0 +1,22 @@
+package com.ossez.jackson.map;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+public class MyPairSerializer extends JsonSerializer {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ @Override
+ public void serialize(MyPair value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
+ StringWriter writer = new StringWriter();
+ mapper.writeValue(writer, value);
+ gen.writeFieldName(writer.toString());
+ }
+}
\ No newline at end of file
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java
new file mode 100644
index 0000000000..202c4c9aea
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java
@@ -0,0 +1,54 @@
+package com.ossez.jackson.mapnull;
+
+public class MyDto {
+
+ private String stringValue;
+ private int intValue;
+ private boolean booleanValue;
+
+ public MyDto() {
+ super();
+ }
+
+ public MyDto(final String stringValue, final int intValue, final boolean booleanValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+ //
+
+ @Override
+ public String toString() {
+ return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]";
+ }
+
+}
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java
new file mode 100644
index 0000000000..299ef45305
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java
@@ -0,0 +1,27 @@
+package com.ossez.jackson.mapnull;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class MyDtoNullKeySerializer extends StdSerializer