#787 - Return all Link attributes on discovery.

This commit is contained in:
Greg Turnquist
2019-02-06 16:23:16 -06:00
parent 9518a2db9a
commit 9e8e57a74b
13 changed files with 230 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@ public class CollectionJsonLinkDiscoverer extends JsonPathLinkDiscoverer {
private final CollectionJsonSelfLinkDiscoverer selfLinkDiscoverer;
public CollectionJsonLinkDiscoverer() {
super("$.collection..links..[?(@.rel == '%s')].href", MediaTypes.COLLECTION_JSON);
this.selfLinkDiscoverer = new CollectionJsonSelfLinkDiscoverer();
}
@@ -117,6 +118,7 @@ public class CollectionJsonLinkDiscoverer extends JsonPathLinkDiscoverer {
* {@link JsonPathLinkDiscoverer} that looks for the non-parameterized {@literal collection.href} link.
*/
private static class CollectionJsonSelfLinkDiscoverer extends JsonPathLinkDiscoverer {
CollectionJsonSelfLinkDiscoverer() {
super("$.collection.href", MediaTypes.COLLECTION_JSON);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,16 +19,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minidev.json.JSONArray;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
@@ -40,6 +40,7 @@ import com.jayway.jsonpath.JsonPath;
* {@link LinkDiscoverer} that uses {@link JsonPath} to find links inside a representation.
*
* @author Oliver Gierke
* @author Greg Turnquist
*/
public class JsonPathLinkDiscoverer implements LinkDiscoverer {
@@ -74,24 +75,15 @@ public class JsonPathLinkDiscoverer implements LinkDiscoverer {
* The template has to contain a single {@code %s} placeholder which will be replaced by the relation type.
*
* @param pathTemplate must not be {@literal null} or empty and contain a single placeholder.
* @param mediaType the primary {@link MediaType}s to support.
* @param others {@link MediaType}s to support.
* @param mediaTypes the {@link MediaType}s to support.
*/
public JsonPathLinkDiscoverer(String pathTemplate, MediaType mediaType, MediaType... others) {
public JsonPathLinkDiscoverer(String pathTemplate, MediaType... mediaTypes) {
Assert.hasText(pathTemplate, "Path template must not be null!");
// Assert.isTrue(StringUtils.countOccurrencesOf(pathTemplate, "%s") == 1,
// "Path template must contain a single placeholder!");
Assert.notNull(mediaType, "Primary MediaType must not be null!");
Assert.notNull(others, "Other MediaTypes must not be null!");
Assert.notNull(mediaTypes, "Primary MediaType must not be null!");
this.pathTemplate = pathTemplate;
List<MediaType> mediaTypes = new ArrayList<>(others.length + 1);
mediaTypes.add(mediaType);
mediaTypes.addAll(Arrays.asList(others));
this.mediaTypes = mediaTypes;
this.mediaTypes = Arrays.asList(mediaTypes);
}
/*
@@ -167,16 +159,33 @@ public class JsonPathLinkDiscoverer implements LinkDiscoverer {
if (parseResult instanceof JSONArray) {
JSONArray array = (JSONArray) parseResult;
JSONArray jsonArray = (JSONArray) parseResult;
return array.stream() //
.map(element -> new Link(element.toString(), rel)) //
return jsonArray.stream() //
.flatMap(element -> (element instanceof JSONArray)
? ((JSONArray) element).stream()
: Stream.of(element))
.map(element -> extractLink(element, rel)) //
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
} else if (parseResult instanceof Map) {
return Collections.singletonList(extractLink(parseResult, rel));
}
return Collections.unmodifiableList(Collections.singletonList(new Link(parseResult.toString(), rel)));
}
/**
* Callback for each {@link LinkDiscoverer} to extract relevant attributes and generate a {@link Link}.
*
* @param element
* @param rel
* @return link
*/
protected Link extractLink(Object element, String rel) {
return new Link(element.toString(), rel);
};
/*
* (non-Javadoc)
* @see org.springframework.plugin.core.Plugin#supports(java.lang.Object)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
*/
package org.springframework.hateoas.hal;
import java.util.Map;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
@@ -23,10 +26,35 @@ import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
* {@link LinkDiscoverer} implementation based on HAL link structure.
*
* @author Oliver Gierke
* @author Greg Turnquist
*/
public class HalLinkDiscoverer extends JsonPathLinkDiscoverer {
/**
* Constructor for {@link MediaTypes#HAL_JSON}.
*/
public HalLinkDiscoverer() {
super("$._links..['%s']..href", MediaTypes.HAL_JSON);
super("$._links..['%s']", MediaTypes.HAL_JSON, MediaTypes.HAL_JSON_UTF8);
}
@Override
@SuppressWarnings("unchecked")
protected Link extractLink(Object element, String rel) {
if (element instanceof Map) {
Map<String, String> json = (Map<String, String>) element;
return new Link(json.get("href"), rel)
.withHreflang(json.get("hreflang"))
.withMedia(json.get("media"))
.withTitle(json.get("title"))
.withType(json.get("type"))
.withDeprecation(json.get("deprecation"))
.withProfile(json.get("profile"))
.withName(json.get("name"));
}
return super.extractLink(element, rel);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
*/
package org.springframework.hateoas.hal.forms;
import java.util.Map;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
@@ -26,6 +29,27 @@ import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
public class HalFormsLinkDiscoverer extends JsonPathLinkDiscoverer {
public HalFormsLinkDiscoverer() {
super("$._links..['%s']..href", MediaTypes.HAL_FORMS_JSON);
super("$._links..['%s']", MediaTypes.HAL_FORMS_JSON);
}
@Override
@SuppressWarnings("unchecked")
protected Link extractLink(Object element, String rel) {
if (element instanceof Map) {
Map<String, String> json = (Map<String, String>) element;
return new Link(json.get("href"), rel)
.withHreflang(json.get("hreflang"))
.withMedia(json.get("media"))
.withTitle(json.get("title"))
.withType(json.get("type"))
.withDeprecation(json.get("deprecation"))
.withProfile(json.get("profile"))
.withName(json.get("name"));
}
return super.extractLink(element, rel);
}
}