├── .gitignore
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── voodoodyne
│ └── jackson
│ └── jsog
│ ├── JSOGGenerator.java
│ ├── JSOGRef.java
│ ├── JSOGRefDeserializer.java
│ └── JSOGRefSerializer.java
└── test
└── java
└── com
└── voodoodyne
└── jackson
└── jsog
├── Issue15Test.java
├── Issue23Test.java
├── Issue3Test.java
├── JSOGTest.java
├── PolymorphicTest.java
└── Thing.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .svn
2 | /target/
3 | /test-output/
4 | .project
5 | .classpath
6 | *.iml
7 | .idea
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Voost LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript Object Graphs with Jackson
2 |
3 | This is a plugin for Jackson which can serialize cyclic object graphs in the [JSOG format](https://github.com/jsog/jsog).
4 | It can both serialize and deserialize.
5 |
6 | Caveat: With Jackson 2.5.0, polymoprhic (ie @JsonTypeInfo) objects cannot be deserialized from JSOG. Jackson 2.5.1
7 | fixes the issue.
8 |
9 | ## Source code
10 |
11 | The official repository is (https://github.com/jsog/jsog-jackson)
12 |
13 | ## Download
14 |
15 | This plugin is available in Maven Central:
16 |
17 |
18 | com.voodoodyne.jackson.jsog
19 | jackson-jsog
20 | please look up latest version
21 | compile
22 |
23 |
24 | It can be downloaded directly from [http://search.maven.org/]
25 |
26 | ## Usage
27 |
28 | To use this plugin, annotate any classes which may contain references with *@JsonIdentityInfo(generator=JSOGGenerator.class)*.
29 |
30 | @JsonIdentityInfo(generator=JSOGGenerator.class)
31 | public class Person {
32 | String name;
33 | Person secretSanta;
34 | }
35 |
36 | ## Author
37 |
38 | * Jeff Schnitzer (jeff@infohazard.org)
39 |
40 | ## License
41 |
42 | This software is provided under the [MIT license](http://opensource.org/licenses/MIT)
43 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 |
5 | UTF-8
6 | 2.10.3
7 |
8 |
9 | com.voodoodyne.jackson.jsog
10 | jackson-jsog
11 | 1.1.3-SNAPSHOT
12 |
13 | Jackson-JSOG
14 | JSOG-generating plugin for Jackson.
15 | jar
16 | http://github.com/jsog/jsog-jackson/
17 |
18 | scm:git:git@github.com:jsog/jsog-jackson.git
19 | scm:git:git@github.com:jsog/jsog-jackson.git
20 | HEAD
21 |
22 |
23 |
24 | MIT License
25 | http://www.opensource.org/licenses/mit-license.php
26 |
27 |
28 |
29 |
30 | jeff
31 | Jeff Schnitzer
32 | jeff@infohazard.org
33 |
34 |
35 | jon
36 | Jon Stevens
37 | latchkey@gmail.com
38 |
39 |
40 |
41 |
42 |
43 | ossrh
44 | https://oss.sonatype.org/content/repositories/snapshots
45 |
46 |
47 | ossrh
48 | Nexus Release Repository
49 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
50 |
51 |
52 |
53 |
54 |
55 | release-sign-artifacts
56 |
57 |
58 | performRelease
59 | true
60 |
61 |
62 |
63 |
64 |
65 | org.apache.maven.plugins
66 | maven-gpg-plugin
67 |
68 |
69 | sign-artifacts
70 | verify
71 |
72 | sign
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | maven-compiler-plugin
86 | 3.8.1
87 |
88 | 1.6
89 | 1.6
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-source-plugin
96 | 3.1.0
97 |
98 |
99 |
100 | jar
101 |
102 |
103 |
104 |
105 |
106 |
107 | org.apache.maven.plugins
108 | maven-javadoc-plugin
109 | 3.1.1
110 |
111 |
112 |
113 | jar
114 |
115 |
116 |
117 |
118 | 6
119 | none
120 |
121 |
122 |
123 |
124 | org.apache.maven.plugins
125 | maven-surefire-plugin
126 | 2.22.2
127 |
128 |
129 | **/*Test*.java
130 |
131 |
132 |
133 |
134 |
135 | org.apache.maven.plugins
136 | maven-release-plugin
137 | 2.5.3
138 |
139 | true
140 | release-sign-artifacts
141 |
142 |
143 |
144 |
145 | org.sonatype.plugins
146 | nexus-staging-maven-plugin
147 | 1.6.8
148 | true
149 |
150 | ossrh
151 | https://oss.sonatype.org/
152 | true
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | com.fasterxml.jackson.core
161 | jackson-core
162 | ${jackson.version}
163 | compile
164 | true
165 |
166 |
167 | com.fasterxml.jackson.core
168 | jackson-databind
169 | ${jackson.version}
170 | compile
171 | true
172 |
173 |
174 |
175 |
176 | org.hamcrest
177 | hamcrest-core
178 | 1.3
179 | test
180 |
181 |
182 | org.hamcrest
183 | hamcrest-library
184 | 1.3
185 | test
186 |
187 |
188 | org.testng
189 | testng
190 | 6.8.5
191 | test
192 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/src/main/java/com/voodoodyne/jackson/jsog/JSOGGenerator.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 |
4 |
5 | import com.fasterxml.jackson.annotation.ObjectIdGenerator;
6 |
7 | /**
8 | * Use this as an object id generator and your class will serialize as jsog.
9 | *
10 | * @author Jeff Schnitzer
11 | */
12 | public class JSOGGenerator extends ObjectIdGenerator {
13 |
14 | private static final long serialVersionUID = 1L;
15 |
16 | protected transient int _nextValue;
17 | protected final Class> _scope;
18 |
19 | public JSOGGenerator() { this(null, -1); }
20 |
21 | public JSOGGenerator(Class> scope, int nextValue) {
22 | _scope = scope;
23 | _nextValue = nextValue;
24 | }
25 |
26 | @Override
27 | public Class> getScope() {
28 | return _scope;
29 | }
30 |
31 | @Override
32 | public boolean canUseFor(ObjectIdGenerator> gen) {
33 | return (gen.getClass() == getClass()) && (gen.getScope() == _scope);
34 | }
35 |
36 | @Override
37 | public ObjectIdGenerator forScope(Class> scope) {
38 | return (_scope == scope) ? this : new JSOGGenerator(scope, _nextValue);
39 | }
40 |
41 | @Override
42 | public ObjectIdGenerator newForSerialization(Object context) {
43 | return new JSOGGenerator(_scope, 1);
44 | }
45 |
46 | @Override
47 | public com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey key(Object key) {
48 | return new IdKey(getClass(), _scope, key);
49 | }
50 |
51 | @Override
52 | public JSOGRef generateId(Object forPojo) {
53 | int id = _nextValue;
54 | ++_nextValue;
55 | return new JSOGRef(id);
56 | }
57 |
58 | @Override
59 | public boolean maySerializeAsObject() {
60 | return true;
61 | }
62 |
63 | @Override
64 | public boolean isValidReferencePropertyName(String name, Object parser) {
65 | return JSOGRef.REF_KEY.equals(name);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/voodoodyne/jackson/jsog/JSOGRef.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 |
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
7 |
8 | /**
9 | * This object lets us persuade jackson into serializing JSOG structures. It is the id generated,
10 | * and a special serializer knows how to convert it to an @id or @ref as appropriate.
11 | *
12 | * @author Jeff Schnitzer
13 | */
14 | @JsonSerialize(using=JSOGRefSerializer.class)
15 | @JsonDeserialize(using=JSOGRefDeserializer.class)
16 | public final class JSOGRef
17 | {
18 | /** */
19 | public static final String REF_KEY = "@ref";
20 |
21 | /** The ref value generated by other serializers might not be numeric, so we use String */
22 | @JsonProperty(REF_KEY)
23 | public String ref;
24 |
25 | /**
26 | * A flag we use to determine if this ref has already been serialized. Because jackson calls the same
27 | * code for serializing both ids and refs, we simply assume the first use is an id and all subsequent
28 | * uses are refs.
29 | */
30 | public transient boolean used;
31 |
32 | /** */
33 | public JSOGRef(String val) {
34 | ref = val;
35 | }
36 |
37 | /** */
38 | public JSOGRef(int val) {
39 | this(Integer.toString(val));
40 | }
41 |
42 | @Override
43 | public boolean equals(Object obj) {
44 | return obj instanceof JSOGRef && ((JSOGRef)obj).ref.equals(ref);
45 | }
46 |
47 | @Override
48 | public int hashCode() {
49 | return ref.hashCode();
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/com/voodoodyne/jackson/jsog/JSOGRefDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 |
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.DeserializationContext;
7 | import com.fasterxml.jackson.databind.JsonDeserializer;
8 | import com.fasterxml.jackson.databind.JsonNode;
9 | import java.io.IOException;
10 |
11 | /**
12 | * Knows how to take either form of a JSOGRef (string or {@ref:string} and convert it back into a JSOGRef.
13 | *
14 | * @author Jeff Schnitzer
15 | */
16 | public class JSOGRefDeserializer extends JsonDeserializer
17 | {
18 | @Override
19 | public JSOGRef deserialize(JsonParser jp, DeserializationContext ctx) throws IOException, JsonProcessingException {
20 | JsonNode node = ctx.readValue(jp, JsonNode.class);
21 | if (node.isTextual()) {
22 | return new JSOGRef(node.asText());
23 | } else {
24 | return new JSOGRef(node.get(JSOGRef.REF_KEY).asText());
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/voodoodyne/jackson/jsog/JSOGRefSerializer.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 |
4 | import java.io.IOException;
5 |
6 | import com.fasterxml.jackson.core.JsonGenerator;
7 | import com.fasterxml.jackson.core.JsonProcessingException;
8 | import com.fasterxml.jackson.databind.JsonSerializer;
9 | import com.fasterxml.jackson.databind.SerializerProvider;
10 |
11 | /**
12 | * Knows how to take a JSOGRef and print it as @id or @ref as appropriate.
13 | *
14 | * @author Jeff Schnitzer
15 | */
16 | public class JSOGRefSerializer extends JsonSerializer
17 | {
18 | @Override
19 | public void serialize(JSOGRef value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
20 | if (value.used) {
21 | jgen.writeStartObject();
22 | jgen.writeObjectField(JSOGRef.REF_KEY, value.ref);
23 | jgen.writeEndObject();
24 | } else {
25 | value.used = true;
26 | jgen.writeObject(value.ref);
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/Issue15Test.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.databind.module.SimpleModule;
6 | import org.testng.annotations.Test;
7 |
8 |
9 | import java.io.IOException;
10 | import java.util.Date;
11 |
12 | /**
13 | * Demonstrates the inability to round trip serialize deserialize when using DefaultTyping.NON_FINAL,
14 | * and version fixes for NON_CONCRETE strategies.
15 | */
16 | public class Issue15Test {
17 |
18 | @Test // always works
19 | public void testIssue5WorkaroundObject() throws IOException {
20 | testWithPolymorphicStrategy(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT);
21 |
22 | }
23 | @Test // works with Jackson 2.5.4+
24 | public void testIssue5WorkaroundObjectAndNonConcrete() throws IOException {
25 | testWithPolymorphicStrategy(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE);
26 |
27 | }
28 | @Test // works with Jackson 2.5.4+
29 | public void testIssue5WorkaroundNonConcreteAndArrays() throws IOException {
30 | testWithPolymorphicStrategy(ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS);
31 |
32 | }
33 | @Test // fails on Jackson 2.8.8 (no working version as of this date) unless JSOGRef is a final class
34 | public void testIssue5WorkaroundNonFinal() throws IOException {
35 | testWithPolymorphicStrategy(ObjectMapper.DefaultTyping.NON_FINAL);
36 | }
37 |
38 | private void testWithPolymorphicStrategy(ObjectMapper.DefaultTyping typingStragegy) throws IOException {
39 | Thing t = new Thing();
40 | t.setName("foo");
41 |
42 | t.setDate(new Date());
43 |
44 | ObjectMapper mapper = new ObjectMapper();
45 | mapper.enableDefaultTyping(typingStragegy);
46 |
47 | // issue is JSOG specific since removing this line causes all tests to
48 | // pass in 2.5.4 (did not test earlier)
49 | mapper.addMixIn(Object.class, JSOGMixin.class);
50 |
51 | // No difference if we use the module workaround from Issue #5
52 |
53 | // SimpleModule jModule = new SimpleModule();
54 | // jModule.setMixInAnnotation(Object.class, JSOGMixin.class);
55 | // mapper.registerModule(jModule);
56 |
57 | String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(t);
58 | mapper.readValue(json, Thing.class);
59 | }
60 |
61 | @JsonIdentityInfo(generator = JSOGGenerator.class) private static class JSOGMixin {}
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/Issue23Test.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.core.type.TypeReference;
6 | import com.fasterxml.jackson.databind.DeserializationFeature;
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 | import org.testng.annotations.Test;
9 |
10 | import java.util.List;
11 |
12 | import static org.hamcrest.MatcherAssert.assertThat;
13 | import static org.hamcrest.Matchers.equalTo;
14 |
15 | public class Issue23Test {
16 |
17 | @JsonIdentityInfo(generator = JSOGGenerator.class)
18 | public static class TestType {
19 | public String value;
20 | }
21 |
22 | @Test
23 | public void shouldDeserializeWithFailOnTrailingTokensFeatureEnabled() throws JsonProcessingException {
24 | // given
25 | ObjectMapper objectMapper = new ObjectMapper().enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
26 |
27 | tryDeserializeAndAssert(objectMapper);
28 | }
29 |
30 | @Test
31 | public void shouldDeserializeWithFailOnTrailingTokensFeatureDisabled() throws JsonProcessingException {
32 | // given
33 | ObjectMapper objectMapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
34 |
35 | tryDeserializeAndAssert(objectMapper);
36 | }
37 |
38 | private void tryDeserializeAndAssert(final ObjectMapper objectMapper) throws JsonProcessingException {
39 | // when
40 | List deserialized = objectMapper.readValue(
41 | "[{\"@id\":\"1\",\"value\":\"testValue\"},{\"@ref\":\"1\"}]",
42 | new TypeReference>() {});
43 | // then
44 | assertThat(deserialized.get(0).value, equalTo("testValue"));
45 | assertThat(deserialized.get(1).value, equalTo("testValue"));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/Issue3Test.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.testng.annotations.Test;
6 | import java.util.List;
7 | import static org.hamcrest.MatcherAssert.assertThat;
8 | import static org.hamcrest.Matchers.equalTo;
9 | import static org.hamcrest.Matchers.hasSize;
10 | import static org.hamcrest.Matchers.sameInstance;
11 |
12 | /**
13 | * Test for https://github.com/jsog/jsog-jackson/issues/3
14 | */
15 | public class Issue3Test {
16 |
17 | @JsonIdentityInfo(generator=JSOGGenerator.class)
18 | public static class ContractNumber {
19 | public Project project;
20 | }
21 |
22 | @JsonIdentityInfo(generator=JSOGGenerator.class)
23 | public static class Project {
24 | public String projectid;
25 | public List contractnumbers;
26 | }
27 |
28 | /**
29 | */
30 | private static final String JSOGIFIED = "{\"@id\":\"1\",\"projectid\":\"1\",\"contractnumbers\":[{\"@id\":\"2\",\"project\":{\"@ref\":\"1\"}}]}";
31 |
32 | /** */
33 | ObjectMapper mapper = new ObjectMapper();
34 |
35 | /**
36 | */
37 | @Test
38 | public void deserializationWorks() throws Exception {
39 | Project project = mapper.readValue(JSOGIFIED, Project.class);
40 |
41 | assertThat(project.projectid, equalTo("1"));
42 | assertThat(project.contractnumbers, hasSize(1));
43 | assertThat(project.contractnumbers.get(0).project, sameInstance(project));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/JSOGTest.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | import com.fasterxml.jackson.annotation.JsonIdentityInfo;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 |
8 | public class JSOGTest {
9 |
10 | @JsonIdentityInfo(generator=JSOGGenerator.class)
11 | public static class Inner {
12 | public String bar;
13 | }
14 |
15 | @JsonIdentityInfo(generator=JSOGGenerator.class)
16 | public static class Outer {
17 | public String foo;
18 | public Inner inner1;
19 | public Inner inner2;
20 | }
21 |
22 | /** Expected output */
23 | private static final String JSOGIFIED = "{\"@id\":\"1\",\"foo\":\"foo\",\"inner1\":{\"@id\":\"2\",\"bar\":\"bar\"},\"inner2\":{\"@ref\":\"2\"}}";
24 |
25 | /** */
26 | ObjectMapper mapper = new ObjectMapper();
27 |
28 | /** */
29 | @Test
30 | public void serializationWorks() throws Exception {
31 | Outer outer = new Outer();
32 | outer.foo = "foo";
33 | outer.inner1 = outer.inner2 = new Inner();
34 | outer.inner1.bar = "bar";
35 |
36 | String jsog = mapper.writeValueAsString(outer);
37 |
38 | System.out.println("Serialized to: " + jsog);
39 |
40 | assert jsog.equals(JSOGIFIED);
41 | }
42 |
43 | /**
44 | */
45 | @Test
46 | public void deserializationWorks() throws Exception {
47 | Outer outer = mapper.readValue(JSOGIFIED, Outer.class);
48 |
49 | assert outer.inner1 == outer.inner2;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/PolymorphicTest.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo;
4 | import com.fasterxml.jackson.annotation.JsonTypeInfo;
5 | import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
6 | import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 | import org.testng.annotations.Test;
9 | import static org.hamcrest.MatcherAssert.assertThat;
10 | import static org.hamcrest.Matchers.equalTo;
11 |
12 | public class PolymorphicTest {
13 |
14 | @JsonIdentityInfo(generator=JSOGGenerator.class)
15 | @JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="@class")
16 | public static class Inner {
17 | public String bar;
18 |
19 | public Inner() {}
20 | public Inner(String bar) { this.bar = bar; }
21 | }
22 |
23 | public static class SubInner extends Inner {
24 | public String extra;
25 |
26 | public SubInner() {}
27 | public SubInner(String bar, String extra) {
28 | super(bar);
29 | this.extra = extra;
30 | }
31 | }
32 |
33 | @JsonIdentityInfo(generator=JSOGGenerator.class)
34 | public static class Outer {
35 | public String foo;
36 | public Inner inner1;
37 | public Inner inner2;
38 | }
39 |
40 | /** Expected output */
41 | private static final String JSOGIFIED = "{\"@id\":\"1\",\"foo\":\"foo\",\"inner1\":{\"@class\":\"com.voodoodyne.jackson.jsog.PolymorphicTest$SubInner\",\"@id\":\"2\",\"bar\":\"bar\",\"extra\":\"extra\"},\"inner2\":{\"@ref\":\"2\"}}";
42 |
43 | /** */
44 | ObjectMapper mapper = new ObjectMapper();
45 |
46 | /** */
47 | @Test
48 | public void serializationWorks() throws Exception {
49 | Outer outer = new Outer();
50 | outer.foo = "foo";
51 | outer.inner1 = outer.inner2 = new SubInner("bar", "extra");
52 |
53 | String jsog = mapper.writeValueAsString(outer);
54 |
55 | System.out.println("Serialized to: " + jsog);
56 |
57 | assertThat(jsog, equalTo(JSOGIFIED));
58 | }
59 |
60 | /**
61 | */
62 | //@Test
63 | public void deserializationWorks() throws Exception {
64 | Outer outer = mapper.readValue(JSOGIFIED, Outer.class);
65 |
66 | assert outer.inner1 == outer.inner2;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/test/java/com/voodoodyne/jackson/jsog/Thing.java:
--------------------------------------------------------------------------------
1 | package com.voodoodyne.jackson.jsog;
2 |
3 | import java.util.Date;
4 |
5 | public class Thing {
6 | private String name;
7 | private Date date;
8 |
9 | public String getName() {
10 | return name;
11 | }
12 |
13 | public void setName(String name) {
14 | this.name = name;
15 | }
16 |
17 | public Date getDate() {
18 | return date;
19 | }
20 |
21 | public void setDate(Date date) {
22 | this.date = date;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------