Skip to content

Commit

Permalink
global: JSON utility moved to typetools-json module, tests
Browse files Browse the repository at this point in the history
Signed-off-by: Ketoth Xupack <ketoth.xupack@gmail.com>
  • Loading branch information
KetothXupack committed Oct 10, 2013
1 parent 6d58432 commit 0e06d4f
Show file tree
Hide file tree
Showing 20 changed files with 383 additions and 116 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* [apptools](projects/apptools)
* [springtools](projects/springtools)
* [typetools](projects/typetools)
* [typetools-json](projects/typetools-json)
* [springapp](projects/springapp)
* [bean-modification-listener](projects/bean-modification-listener)
* [jongo](projects/jongo)
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<module>projects/jsr305-aspectj-validation</module>
<module>projects/slf4j-logging</module>
<module>projects/typetools</module>
<module>projects/typetools-json</module>
<module>projects/springtools</module>
<module>projects/apptools</module>
<module>projects/springapp</module>
Expand Down
24 changes: 12 additions & 12 deletions projects/jongo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.no-hope</groupId>
<artifactId>slf4j-logging</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.no-hope</groupId>
<artifactId>typetools-json</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand Down Expand Up @@ -78,18 +90,6 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.no-hope</groupId>
<artifactId>slf4j-logging</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.no-hope</groupId>
<artifactId>typetools</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
94 changes: 94 additions & 0 deletions projects/typetools-json/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>typetools-json</artifactId>
<packaging>jar</packaging>

<description>A set of tools aimed to make daily programming easier.</description>

<prerequisites>
<maven>3.0</maven>
</prerequisites>

<parent>
<groupId>org.no-hope</groupId>
<artifactId>java-toolkit</artifactId>
<version>0.1.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<!-- enforce @Nonnull checks -->
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries>
<aspectLibrary>
<groupId>org.no-hope</groupId>
<artifactId>jsr305-aspectj-validation</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.no-hope</groupId>
<artifactId>jsr305-aspectj-validation</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.no-hope</groupId>
<artifactId>slf4j-logging</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>

<!-- Json parser -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>${jackson.version}</version>
<exclusions>
<exclusion>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
*/
public final class JSON {
public static final JSON JSON = new JSON(new ObjectMapper(), true);

private static final Logger LOG = LoggerFactory.getLogger(JSON.class);

private final ObjectMapper usualMapper;
private final ObjectMapper prettyMapper;

Expand All @@ -32,15 +32,14 @@ private JSON(final ObjectMapper mapper, final boolean builtin) {
usualMapper.setSerializationInclusion(NON_EMPTY);
usualMapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL, "@class");
usualMapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(ANY));
usualMapper.configure(FAIL_ON_EMPTY_BEANS, false);
}

prettyMapper = usualMapper.copy();
prettyMapper.configure(INDENT_OUTPUT, true);
prettyMapper.configure(WRITE_DATES_AS_TIMESTAMPS, false);
prettyMapper.configure(FAIL_ON_EMPTY_BEANS, false);
}


public static JSON customize(final ObjectMapper mapper) {
return customize(mapper, true);
}
Expand All @@ -49,6 +48,28 @@ public static JSON customize(final ObjectMapper mapper, final boolean builtin) {
return new JSON(mapper, builtin);
}

@SuppressWarnings("PMD.AvoidCatchingThrowable")
private static Object jsonifyWith(final ObjectMapper mapper, final Object obj, final String onErrorMessage) {
return new Object() {
@Override
public String toString() {
try {
return mapper.writeValueAsString(obj);
} catch (final Throwable e) {
LOG.error(e, "Unable to jsonify object of class {}", obj == null ? null : obj.getClass());
return onErrorMessage;
}
}
};
}

private static String defaultErrorMessage(final Object obj) {
if (null != obj) {
return "<? " + obj.getClass().getCanonicalName() + " />";
}
return "<? null />";
}

public Object pretty(final Object obj) {
return pretty(obj, defaultErrorMessage(obj));
}
Expand All @@ -64,7 +85,7 @@ public Object jsonify(final Object obj) {
* @throws IOException
*/
public <T> T copyAs(final Object source, final Class<T> clazz) throws IOException {
final byte [] marshalled = usualMapper.writeValueAsBytes(source);
final byte[] marshalled = usualMapper.writeValueAsBytes(source);
return usualMapper.readValue(marshalled, clazz);
}

Expand All @@ -74,29 +95,7 @@ private Object jsonify(final Object obj,
}

private Object pretty(final Object obj,
final String onErrorMessage) {
final String onErrorMessage) {
return jsonifyWith(prettyMapper, obj, onErrorMessage);
}

@SuppressWarnings("PMD.AvoidCatchingThrowable")
private static Object jsonifyWith(final ObjectMapper mapper, final Object obj, final String onErrorMessage) {
return new Object() {
@Override
public String toString() {
try {
return mapper.writeValueAsString(obj);
} catch (final Throwable e) {
LOG.error(e, "Unable to jsonify object of class {}", obj == null ? null : obj.getClass());
return onErrorMessage;
}
}
};
}

private static String defaultErrorMessage(final Object obj) {
if (null != obj) {
return "<? " + obj.getClass().getCanonicalName() + "/>";
}
return "<?null />";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ protected ColorSerializer() {
}

@Override
public void serialize(final Color value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
public void serialize(final Color value, final JsonGenerator jgen, final SerializerProvider provider)
throws IOException {
jgen.writeStartArray();
for (final float v:value.getRGBComponents(null)) {
for (final float v : value.getRGBComponents(null)) {
jgen.writeNumber(v);
}
jgen.writeEndArray();
}

@Override
public JsonNode getSchema(final SerializerProvider provider, final java.lang.reflect.Type typeHint)
{
public JsonNode getSchema(final SerializerProvider provider, final java.lang.reflect.Type typeHint) {
return createSchemaNode("array", true);
}

@Override
public void serializeWithType(final Color value, final JsonGenerator jgen, final SerializerProvider provider, final TypeSerializer typeSer) throws IOException {
public void serializeWithType(final Color value, final JsonGenerator jgen, final SerializerProvider provider, final TypeSerializer typeSer)
throws IOException {
typeSer.writeTypePrefixForScalar(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForScalar(value, jgen);
Expand Down Expand Up @@ -89,7 +90,8 @@ public Color deserialize(final JsonParser jp, final DeserializationContext ctxt)
}

@Override
public Object deserializeWithType(final JsonParser jp, final DeserializationContext ctxt, final TypeDeserializer typeDeserializer) throws IOException {
public Object deserializeWithType(final JsonParser jp, final DeserializationContext ctxt, final TypeDeserializer typeDeserializer)
throws IOException {
return typeDeserializer.deserializeTypedFromAny(jp, ctxt);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.nohope.typetools;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;

/**
* Date: 11/8/12
* Time: 3:28 PM
*/
public class JSONTest {

public static class Bean {
private final String a;
private final Integer b;

// used for de-serialization only
private Bean() {
a = null;
b = null;
}

public Bean(final String a, final Integer b) {
this.a = a;
this.b = b;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

final Bean bean = (Bean) o;
return a.equals(bean.a) && b.equals(bean.b);
}

@Override
public int hashCode() {
int result = a.hashCode();
result = 31 * result + b.hashCode();
return result;
}
}

public static class CycleBean {
private final CycleBean a;

public CycleBean() {
this.a = this;
}
}


@Test
public void jsonSerialization() throws Exception {
final Bean object = new Bean("x", 1);

for (final JSON json : Arrays.asList(JSON.JSON, JSON.customize(new ObjectMapper()))) {
assertEquals("{\"@class\":\"org.nohope.typetools.JSONTest$Bean\",\"a\":\"x\",\"b\":1}",
json.jsonify(object).toString());
assertEquals("{\n"
+ " \"@class\" : \"org.nohope.typetools.JSONTest$Bean\",\n"
+ " \"a\" : \"x\",\n"
+ " \"b\" : 1\n"
+ "}",
json.pretty(object).toString());
}

final JSON custom = JSON.customize(new ObjectMapper(), false);
assertEquals("<? org.nohope.typetools.JSONTest.Bean />", custom.jsonify(object).toString());
assertEquals("<? org.nohope.typetools.JSONTest.Bean />", custom.pretty(object).toString());

assertEquals(object, JSON.JSON.copyAs(object, Bean.class));

assertEquals("null", JSON.JSON.pretty(null).toString());
assertEquals("null", JSON.JSON.jsonify(null).toString());
}

@Test
public void errorneousJsonSerialization() throws Exception {
final CycleBean object = new CycleBean();
assertEquals("<? org.nohope.typetools.JSONTest.CycleBean />", JSON.JSON.jsonify(object).toString());
assertEquals("<? org.nohope.typetools.JSONTest.CycleBean />", JSON.JSON.pretty(object).toString());

assertEquals(null, JSON.JSON.copyAs(null, CycleBean.class));
}
}
Loading

0 comments on commit 0e06d4f

Please sign in to comment.