#229 - Added support for curies in HalEmbeddedBuilder.

HalEmbeddedBuilder now takes an optional CurieProvider to create namespaced rels for embeddededs.

Original pull request: #233.
This commit is contained in:
Jeff Stano
2014-08-22 08:46:47 -06:00
committed by Oliver Gierke
parent 994347c005
commit 3ca6fa5504
7 changed files with 127 additions and 93 deletions

View File

@@ -25,6 +25,7 @@ import org.springframework.hateoas.Links;
*
* @see http://tools.ietf.org/html/draft-kelly-json-hal#section-8.2
* @author Oliver Gierke
* @author Jeff Stano
* @since 0.9
*/
public interface CurieProvider {
@@ -38,6 +39,16 @@ public interface CurieProvider {
*/
String getNamespacedRelFrom(Link link);
/**
* Returns the rel to be rendered for the given rel. Will potentially prefix the rel but also might decide not to,
* depending on the actual rel.
*
* @param rel
* @return
* @since 0.17
*/
String getNamespacedRelFor(String rel);
/**
* Returns an object to render as the base curie information. Implementations have to make sure, the retunred
* instances renders as defined in the spec.

View File

@@ -28,6 +28,7 @@ import org.springframework.util.Assert;
* Default implementation of {@link CurieProvider} rendering a single configurable {@link UriTemplate} based curie.
*
* @author Oliver Gierke
* @author Jeff Stano
* @since 0.9
*/
public class DefaultCurieProvider implements CurieProvider {
@@ -65,8 +66,15 @@ public class DefaultCurieProvider implements CurieProvider {
*/
@Override
public String getNamespacedRelFrom(Link link) {
return getNamespacedRelFor(link.getRel());
}
String rel = link.getRel();
/*
* (non-Javadoc)
* @see org.springframework.hateoas.hal.CurieProvider#getNamespacedRelFrom(java.lang.String)
*/
@Override
public String getNamespacedRelFor(String rel) {
boolean prefixingNeeded = !IanaRels.isIanaRel(rel) && !rel.contains(":");
return prefixingNeeded ? String.format("%s:%s", curie.name, rel) : rel;

View File

@@ -42,6 +42,7 @@ class HalEmbeddedBuilder {
private final Map<String, Object> embeddeds = new HashMap<String, Object>();
private final RelProvider provider;
private final CurieProvider curieProvider;
private final EmbeddedWrappers wrappers;
/**
@@ -50,11 +51,12 @@ class HalEmbeddedBuilder {
* @param provider can be {@literal null}.
* @param preferCollectionRels whether to prefer to ask the provider for collection rels.
*/
public HalEmbeddedBuilder(RelProvider provider, boolean preferCollectionRels) {
public HalEmbeddedBuilder(RelProvider provider, CurieProvider curieProvider, boolean preferCollectionRels) {
Assert.notNull(provider, "Relprovider must not be null!");
this.provider = provider;
this.curieProvider = curieProvider;
this.wrappers = new EmbeddedWrappers(preferCollectionRels);
}
@@ -62,7 +64,7 @@ class HalEmbeddedBuilder {
* Adds the given value to the embeddeds. Will skip doing so if the value is {@literal null} or the content of a
* {@link Resource} is {@literal null}.
*
* @param value can be {@literal null}.
* @param source can be {@literal null}.
*/
public void add(Object source) {
@@ -116,6 +118,11 @@ class HalEmbeddedBuilder {
Class<?> type = wrapper.getRelTargetType();
String rel = forCollection ? provider.getCollectionResourceRelFor(type) : provider.getItemResourceRelFor(type);
if (curieProvider != null) {
rel = curieProvider.getNamespacedRelFor(rel);
}
return rel == null ? DEFAULT_REL : rel;
}

View File

@@ -238,18 +238,22 @@ public class Jackson2HalModule extends SimpleModule {
private final BeanProperty property;
private final RelProvider relProvider;
private final CurieProvider curieProvider;
private final boolean enforceEmbeddedCollections;
public HalResourcesSerializer(RelProvider relPorvider, boolean enforceEmbeddedCollections) {
this(null, relPorvider, enforceEmbeddedCollections);
public HalResourcesSerializer(RelProvider relPorvider, CurieProvider curieProvider,
boolean enforceEmbeddedCollections) {
this(null, relPorvider, curieProvider, enforceEmbeddedCollections);
}
public HalResourcesSerializer(BeanProperty property, RelProvider relProvider, boolean enforceEmbeddedCollections) {
public HalResourcesSerializer(BeanProperty property, RelProvider relProvider, CurieProvider curieProvider,
boolean enforceEmbeddedCollections) {
super(Collection.class, false);
this.property = property;
this.relProvider = relProvider;
this.curieProvider = curieProvider;
this.enforceEmbeddedCollections = enforceEmbeddedCollections;
}
@@ -263,7 +267,7 @@ public class Jackson2HalModule extends SimpleModule {
public void serialize(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
HalEmbeddedBuilder builder = new HalEmbeddedBuilder(relProvider, enforceEmbeddedCollections);
HalEmbeddedBuilder builder = new HalEmbeddedBuilder(relProvider, curieProvider, enforceEmbeddedCollections);
for (Object resource : value) {
builder.add(resource);
@@ -275,7 +279,7 @@ public class Jackson2HalModule extends SimpleModule {
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException {
return new HalResourcesSerializer(property, relProvider, enforceEmbeddedCollections);
return new HalResourcesSerializer(property, relProvider, curieProvider, enforceEmbeddedCollections);
}
@Override
@@ -600,7 +604,7 @@ public class Jackson2HalModule extends SimpleModule {
public HalHandlerInstantiator(RelProvider resolver, CurieProvider curieProvider, boolean enforceEmbeddedCollections) {
Assert.notNull(resolver, "RelProvider must not be null!");
this.instanceMap.put(HalResourcesSerializer.class, new HalResourcesSerializer(resolver,
this.instanceMap.put(HalResourcesSerializer.class, new HalResourcesSerializer(resolver, curieProvider,
enforceEmbeddedCollections));
this.instanceMap.put(HalLinkListSerializer.class, new HalLinkListSerializer(curieProvider));
}