Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Serialization is similar to the normal JSON serialization using the `HALMapper`
`ObjectMapper`.

```java
ObjectMapper halMapper = new HALMapper();
ObjectMapper halMapper = HALMapper.create();
String json = halMapper.writeValueAsString(new POJO());
```

Expand All @@ -196,7 +196,7 @@ String json = halMapper.writeValueAsString(new POJO());
Deserialization is also similar to the normal JSON handling using the `HALMapper`.

```java
ObjectMapper halMapper = new HALMapper();
ObjectMapper halMapper = HALMapper.create();
POJO value = halMapper.readValue("{..json..}", POJO.class);
```

Expand All @@ -211,7 +211,7 @@ public class MyApplication extends Application {
private final Set<Object> singletons = new HashSet<>();

public MyApplication() {
singletons.add(new JacksonJsonProvider(new HALMapper()));
singletons.add(new JacksonJsonProvider(HALMapper.create()));
}

@Override
Expand All @@ -228,7 +228,7 @@ jackson-jaxrs-providers can be used to register the `HALMapper`.

```java
ClientBuilder cb = ClientBuilder.newBuilder();
Client client = cb.register(new JacksonJsonProvider(new HALMapper())).build();
Client client = cb.register(new JacksonJsonProvider(HALMapper.create())).build();
```
## HALLink extended with temporal aspect
The HALLink is extended with a `seen` property. This is beyond the current specification of HAL.
Expand Down
53 changes: 53 additions & 0 deletions jackson-dataformat-hal-core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>

<parent>
<groupId>io.openapitools.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-hal-parent</artifactId>
<version>1.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>jackson-dataformat-hal-core</artifactId>
<packaging>jar</packaging>

<name>Jackson HAL Dataformat Core</name>
<description>Core module for shared jackson-dataformat-hal functionality.</description>

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

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${org.slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

61 changes: 61 additions & 0 deletions jackson-dataformat-hal-v2/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.openapitools.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-hal-parent</artifactId>
<version>1.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<name>Jackson HAL Dataformat</name>
<artifactId>jackson-dataformat-hal</artifactId>
<packaging>jar</packaging>

<description>Dataformat extension for Jackson to handle the HAL JSON format.</description>

<dependencies>
<dependency>
<groupId>io.openapitools.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-hal-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${org.slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
61 changes: 61 additions & 0 deletions jackson-dataformat-hal-v3/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.openapitools.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-hal-parent</artifactId>
<version>1.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<name>Jackson3 HAL Dataformat</name>
<artifactId>jackson-hal</artifactId>
<packaging>jar</packaging>

<description>Dataformat extension for Jackson to handle the HAL JSON format.</description>

<dependencies>
<dependency>
<groupId>io.openapitools.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-hal-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${tools.jackson.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${org.slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${org.mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.openapitools.jackson.hal;

import tools.jackson.databind.json.JsonMapper;

public class HALMapper {

private HALMapper() {}

public static JsonMapper.Builder builder() {
return JsonMapper.builder()
.addModule(new JacksonHALModule());
}

public static JsonMapper create() {
return builder() .build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.openapitools.jackson.hal;

import io.openapitools.jackson.dataformat.hal.annotation.EmbeddedResource;
import io.openapitools.jackson.dataformat.hal.annotation.Link;
import io.openapitools.jackson.dataformat.hal.annotation.Resource;
import io.openapitools.jackson.hal.deser.HALBeanDeserializerModifier;
import io.openapitools.jackson.hal.ser.HALBeanSerializerModifier;
import tools.jackson.databind.module.SimpleModule;

/**
* Module registering handlers for the {@link Resource} and {@link EmbeddedResource} annonations as well as the
* {@link Link} annotation.
*/
public class JacksonHALModule extends SimpleModule {

public JacksonHALModule() {
super("JacksonHALModule", PackageVersion.VERSION);
}

@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addSerializerModifier(new HALBeanSerializerModifier());
context.addDeserializerModifier(new HALBeanDeserializerModifier());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package io.openapitools.jackson.hal;

import tools.jackson.core.Version;
import tools.jackson.core.Versioned;
import tools.jackson.core.util.VersionUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* Reading module version from Maven properties files.
*/
public final class PackageVersion implements Versioned {

public static final Version VERSION;

private static final String MAVEN_PROPERTIES = "/META-INF/maven/io.openapitools.jackson.dataformat/jackson-dataformat-hal/pom.properties";

static {
Version version = Version.unknownVersion();
InputStream is = PackageVersion.class.getResourceAsStream(MAVEN_PROPERTIES);
if (is != null) {
try {
Properties p = new Properties();
p.load(is);
version = VersionUtil.parseVersion(p.getProperty("version"), p.getProperty("groupId"), p.getProperty("artifactId"));
} catch (IOException e) {
// Silently ignore
} finally {
try {
is.close();
} catch (IOException ex) {
// Ignore
}
}
}
VERSION = version;
}

@Override
public Version version() {
return VERSION;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.openapitools.jackson.hal.deser;

import io.openapitools.jackson.dataformat.hal.deser.CurieMap;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonParser;
import tools.jackson.core.TreeNode;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.deser.bean.BeanDeserializerBase;
import tools.jackson.databind.deser.std.DelegatingDeserializer;
import tools.jackson.databind.node.ArrayNode;
import tools.jackson.databind.node.ObjectNode;
import java.net.URI;
import java.util.Map;
import java.util.stream.StreamSupport;

/**
* Deserializer to handle incoming application/hal+json. The de-serializer is responsible for intercepting
* the reserved properties (<code>_links</code> and <code>_embedded</code>) and mapping the properties of these
* objects in the incoming json to the uniquely assigned properties of the POJO class.
*/
public class HALBeanDeserializer extends DelegatingDeserializer {

public HALBeanDeserializer(BeanDeserializerBase delegate) {
super(delegate);
}

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws JacksonException {
TreeNode tn = ctxt.readTree(p);
if (tn.isObject()) {
ObjectNode root = (ObjectNode) tn;
for (ReservedProperty rp : ReservedProperty.values()) {
ObjectNode on = (ObjectNode) tn.get(rp.getPropertyName());
if (on != null) {
CurieMap curieMap = createCurieMap(rp, on);
on.remove("curies");

for (Map.Entry<String, JsonNode> jn : on.properties()) {
String propertyName = curieMap.resolve(jn.getKey()).map(URI::toString).orElse(jn.getKey());
root.set(rp.alternateName(propertyName), jn.getValue());
}

root.remove(rp.getPropertyName());
}

}
}

final JsonParser modifiedParser = tn.traverse(p.objectReadContext());
modifiedParser.nextToken();
return _delegatee.deserialize(modifiedParser, ctxt);
}

private CurieMap createCurieMap(ReservedProperty rp, ObjectNode on) {
if (ReservedProperty.LINKS.equals(rp) && on.has("curies")) {
ArrayNode curies = (ArrayNode) on.get("curies");
return new CurieMap(StreamSupport.stream(curies.spliterator(), false)
.map(n -> createMapping((ObjectNode) n)).toArray(CurieMap.Mapping[]::new));
} else {
return new CurieMap();
}
}

private CurieMap.Mapping createMapping(ObjectNode node) {
return new CurieMap.Mapping(node.get("name").asString(), node.get("href").asString());
}

@Override
protected ValueDeserializer<?> newDelegatingInstance(ValueDeserializer<?> newDelegatee) {
return new HALBeanDeserializer((BeanDeserializerBase) newDelegatee);
}
}
Loading