#1116 - Revisit factory methods of RepresentationModel.

This commit introduces ….of(…) factory methods on all RepresentationModel types as well as Link. RepresentationModel.of(…) transparently creates a EntityModel or CollectionModel depending on the value handed into the method.
This commit is contained in:
Oliver Drotbohm
2019-11-18 20:15:41 +01:00
parent 37896bc244
commit 60cf2a828e
78 changed files with 966 additions and 594 deletions

View File

@@ -48,7 +48,9 @@ public class CollectionModel<T> extends RepresentationModel<CollectionModel<T>>
*
* @param content must not be {@literal null}.
* @param links the links to be added to the {@link CollectionModel}.
* @deprecated since 1.1, use {@link #of(Iterable, Link...)} instead.
*/
@Deprecated
public CollectionModel(Iterable<T> content, Link... links) {
this(content, Arrays.asList(links));
}
@@ -58,7 +60,9 @@ public class CollectionModel<T> extends RepresentationModel<CollectionModel<T>>
*
* @param content must not be {@literal null}.
* @param links the links to be added to the {@link CollectionModel}.
* @deprecated since 1.1, use {@link #of(Iterable, Iterable)} instead.
*/
@Deprecated
public CollectionModel(Iterable<T> content, Iterable<Link> links) {
Assert.notNull(content, "Content must not be null!");
@@ -68,9 +72,56 @@ public class CollectionModel<T> extends RepresentationModel<CollectionModel<T>>
for (T element : content) {
this.content.add(element);
}
this.add(links);
}
/**
* Creates a new empty collection model.
*
* @param <T>
* @return
*/
public static <T> CollectionModel<T> empty() {
return of(Collections.emptyList());
}
/**
* Creates a {@link CollectionModel} instance with the given content.
*
* @param content must not be {@literal null}.
* @param links the links to be added to the {@link CollectionModel}.
* @return
* @since 1.1
*/
public static <T> CollectionModel<T> of(Iterable<T> content) {
return of(content, Collections.emptyList());
}
/**
* Creates a {@link CollectionModel} instance with the given content and {@link Link}s (optional).
*
* @param content must not be {@literal null}.
* @param links the links to be added to the {@link CollectionModel}.
* @return
* @since 1.1
*/
public static <T> CollectionModel<T> of(Iterable<T> content, Link... links) {
return of(content, Arrays.asList(links));
}
/**
* s Creates a {@link CollectionModel} instance with the given content and {@link Link}s.
*
* @param content must not be {@literal null}.
* @param links the links to be added to the {@link CollectionModel}.
* @return
* @since 1.1
*/
public static <T> CollectionModel<T> of(Iterable<T> content, Iterable<Link> links) {
return new CollectionModel<>(content, links);
}
/**
* Creates a new {@link CollectionModel} instance by wrapping the given domain class instances into a
* {@link EntityModel}.
@@ -86,10 +137,10 @@ public class CollectionModel<T> extends RepresentationModel<CollectionModel<T>>
ArrayList<T> resources = new ArrayList<>();
for (S element : content) {
resources.add((T) new EntityModel<>(element));
resources.add((T) EntityModel.of(element));
}
return new CollectionModel<>(resources);
return CollectionModel.of(resources);
}
/**

View File

@@ -17,6 +17,7 @@ package org.springframework.hateoas;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -49,7 +50,9 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
*
* @param content must not be {@literal null}.
* @param links the links to add to the {@link EntityModel}.
* @deprecated since 1.1, use {@link #of(Object, Link...)} instead.
*/
@Deprecated
public EntityModel(T content, Link... links) {
this(content, Arrays.asList(links));
}
@@ -59,15 +62,54 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
*
* @param content must not be {@literal null}.
* @param links the links to add to the {@link EntityModel}.
* @deprecated since 1.1, use {@link #of(Object, Iterable)} instead.
*/
public EntityModel(@Nullable T content, Iterable<Link> links) {
@Deprecated
public EntityModel(T content, Iterable<Link> links) {
Assert.notNull(content, "Content must not be null!");
Assert.isTrue(!(content instanceof Collection), "Content must not be a collection! Use Resources instead!");
Assert.isTrue(!(content instanceof Collection), "Content must not be a collection! Use CollectionModel instead!");
this.content = content;
this.add(links);
}
/**
* Creates a new {@link EntityModel} with the given content.
*
* @param content must not be {@literal null}.
* @param links the links to add to the {@link EntityModel}.
* @return
* @since 1.1
*/
public static <T> EntityModel<T> of(T content) {
return of(content, Collections.emptyList());
}
/**
* Creates a new {@link EntityModel} with the given content and {@link Link}s (optional).
*
* @param content must not be {@literal null}.
* @param links the links to add to the {@link EntityModel}.
* @return
* @since 1.1
*/
public static <T> EntityModel<T> of(T content, Link... links) {
return of(content, Arrays.asList(links));
}
/**
* Creates a new {@link EntityModel} with the given content and {@link Link}s.
*
* @param content must not be {@literal null}.
* @param links the links to add to the {@link EntityModel}.
* @return
* @since 1.1
*/
public static <T> EntityModel<T> of(T content, Iterable<Link> links) {
return new EntityModel<>(content, links);
}
/**
* Returns the underlying entity.
*
@@ -81,7 +123,9 @@ public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
// Hacks to allow deserialization into an EntityModel<Map<String, Object>>
@Nullable
@JsonAnyGetter
@SuppressWarnings("unchecked")
private Map<String, Object> getMapContent() {
return Map.class.isInstance(content) ? (Map<String, Object>) content : null;
}

View File

@@ -105,7 +105,9 @@ public class Link implements Serializable {
*
* @see IanaLinkRelations#SELF
* @param href must not be {@literal null} or empty.
* @deprecated since 1.1, use {@link #of(String)}
*/
@Deprecated
public Link(String href) {
this(href, IanaLinkRelations.SELF);
}
@@ -115,7 +117,9 @@ public class Link implements Serializable {
*
* @param href must not be {@literal null} or empty.
* @param rel must not be {@literal null} or empty.
* @deprecated since 1.1, use {@link #of(String, String)}.
*/
@Deprecated
public Link(String href, String rel) {
this(UriTemplate.of(href), LinkRelation.of(rel));
}
@@ -125,7 +129,9 @@ public class Link implements Serializable {
*
* @param href must not be {@literal null} or empty.
* @param rel must not be {@literal null} or empty.
* @deprecated since 1.1, use {@link #of(String, LinkRelation)}.
*/
@Deprecated
public Link(String href, LinkRelation rel) {
this(UriTemplate.of(href), rel);
}
@@ -135,7 +141,9 @@ public class Link implements Serializable {
*
* @param template must not be {@literal null}.
* @param rel must not be {@literal null} or empty.
* @deprecated since 1.1, use {@link #of(UriTemplate, String)}.
*/
@Deprecated
public Link(UriTemplate template, String rel) {
this(template, LinkRelation.of(rel));
}
@@ -145,7 +153,9 @@ public class Link implements Serializable {
*
* @param template must not be {@literal null}.
* @param rel must not be {@literal null} or empty.
* @deprecated since 1.1, use {@link #of(UriTemplate, LinkRelation)}.
*/
@Deprecated
public Link(UriTemplate template, LinkRelation rel) {
this(template, rel, Collections.emptyList());
}
@@ -168,6 +178,67 @@ public class Link implements Serializable {
this.affordances = affordances;
}
/**
* Creates a new link to the given URI with the self relation.
*
* @see IanaLinkRelations#SELF
* @param href must not be {@literal null} or empty.
* @return
* @since 1.1
*/
public static Link of(String href) {
return new Link(href);
}
/**
* Creates a new {@link Link} to the given href with the given relation.
*
* @param href must not be {@literal null} or empty.
* @param relation must not be {@literal null} or empty.
* @return
* @since 1.1
*/
@Deprecated
public static Link of(String href, String relation) {
return new Link(href, relation);
}
/**
* Creates a new {@link Link} to the given href and {@link LinkRelation}.
*
* @param href must not be {@literal null} or empty.
* @param relation must not be {@literal null}.
* @return
* @since 1.1
*/
public static Link of(String href, LinkRelation relation) {
return new Link(href, relation);
}
/**
* Creates a new {@link Link} to the given {@link UriTemplate} and link relation.
*
* @param template must not be {@literal null}.
* @param relation must not be {@literal null} or empty.
* @return
* @since 1.1
*/
public static Link of(UriTemplate template, String relation) {
return new Link(template, relation);
}
/**
* Creates a new {@link Link} to the given {@link UriTemplate} and {@link LinkRelation}.
*
* @param template must not be {@literal null}.
* @param relation must not be {@literal null}.
* @return
* @since 1.1
*/
public static Link of(UriTemplate template, LinkRelation relation) {
return new Link(template, relation);
}
/**
* Empty constructor required by the marshaling framework.
*/
@@ -272,7 +343,7 @@ public class Link implements Serializable {
* @return
*/
public Link expand(Object... arguments) {
return new Link(template.expand(arguments).toString(), getRel());
return of(template.expand(arguments).toString(), getRel());
}
/**
@@ -282,7 +353,7 @@ public class Link implements Serializable {
* @return
*/
public Link expand(Map<String, ?> arguments) {
return new Link(template.expand(arguments).toString(), getRel());
return of(template.expand(arguments).toString(), getRel());
}
/**
@@ -416,7 +487,7 @@ public class Link implements Serializable {
throw new IllegalArgumentException("Link does not provide a rel attribute!");
}
Link link = new Link(matcher.group(1), attributes.get("rel"));
Link link = of(matcher.group(1), attributes.get("rel"));
if (attributes.containsKey("hreflang")) {
link = link.withHreflang(attributes.get("hreflang"));

View File

@@ -18,6 +18,7 @@ package org.springframework.hateoas;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import org.springframework.lang.Nullable;
@@ -51,7 +52,9 @@ public class PagedModel<T> extends CollectionModel<T> {
* @param content must not be {@literal null}.
* @param metadata
* @param links
* @deprectated since 1.1, use {@link #of(Collection, PageMetadata, Link...)} instead.
*/
@Deprecated
public PagedModel(Collection<T> content, @Nullable PageMetadata metadata, Link... links) {
this(content, metadata, Arrays.asList(links));
}
@@ -62,7 +65,9 @@ public class PagedModel<T> extends CollectionModel<T> {
* @param content must not be {@literal null}.
* @param metadata
* @param links
* @deprectated since 1.1, use {@link #of(Collection, PageMetadata, Iterable)} instead.
*/
@Deprecated
public PagedModel(Collection<T> content, @Nullable PageMetadata metadata, Iterable<Link> links) {
super(content, links);
@@ -70,6 +75,62 @@ public class PagedModel<T> extends CollectionModel<T> {
this.metadata = metadata;
}
/**
* Creates an empty {@link PagedModel}.
*
* @param <T>
* @return
* @since 1.1
*/
public static <T> PagedModel<T> empty() {
return empty(null);
}
/**
* Creates an empty {@link PagedModel} with the given {@link PageMetadata}.
*
* @param <T>
* @param metadata can be {@literal null}.
* @return
* @since 1.1
*/
public static <T> PagedModel<T> empty(@Nullable PageMetadata metadata) {
return of(Collections.emptyList(), metadata);
}
/**
* Creates a new {@link PagedModel} from the given content, {@link PageMetadata} and {@link Link}s (optional).
*
* @param content must not be {@literal null}.
* @param metadata can be {@literal null}.
* @param links
*/
public static <T> PagedModel<T> of(Collection<T> content, @Nullable PageMetadata metadata) {
return new PagedModel<>(content, metadata);
}
/**
* Creates a new {@link PagedModel} from the given content, {@link PageMetadata} and {@link Link}s (optional).
*
* @param content must not be {@literal null}.
* @param metadata can be {@literal null}.
* @param links
*/
public static <T> PagedModel<T> of(Collection<T> content, @Nullable PageMetadata metadata, Link... links) {
return new PagedModel<>(content, metadata, Arrays.asList(links));
}
/**
* Creates a new {@link PagedModel} from the given content {@link PageMetadata} and {@link Link}s.
*
* @param content must not be {@literal null}.
* @param metadata can be {@literal null}.
* @param links
*/
public static <T> PagedModel<T> of(Collection<T> content, @Nullable PageMetadata metadata, Iterable<Link> links) {
return new PagedModel<>(content, metadata, links);
}
/**
* Returns the pagination metadata.
*
@@ -95,10 +156,10 @@ public class PagedModel<T> extends CollectionModel<T> {
ArrayList<T> resources = new ArrayList<>();
for (S element : content) {
resources.add((T) new EntityModel<>(element));
resources.add((T) EntityModel.of(element));
}
return new PagedModel<>(resources, metadata);
return PagedModel.of(resources, metadata);
}
/**

View File

@@ -17,6 +17,8 @@ package org.springframework.hateoas;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
@@ -50,12 +52,48 @@ public class RepresentationModel<T extends RepresentationModel<? extends T>> {
this.links.add(initialLink);
}
public RepresentationModel(List<Link> initialLinks) {
public RepresentationModel(Iterable<Link> initialLinks) {
Assert.notNull(initialLinks, "initialLinks must not be null!");
this.links = new ArrayList<>();
this.links.addAll(initialLinks);
for (Link link : initialLinks) {
this.links.add(link);
}
}
/**
* Creates a new {@link RepresentationModel} for the given content object and no links.
*
* @param object can be {@literal null}.
* @return
* @see #of(Object, Iterable)
*/
public static <T> RepresentationModel<?> of(@Nullable T object) {
return of(object, Collections.emptyList());
}
/**
* Creates a new {@link RepresentationModel} for the given content object and links. Will return a simple
* {@link RepresentationModel} if the content is {@literal null}, a {@link CollectionModel} in case the given content
* object is a {@link Collection} or an {@link EntityModel} otherwise.
*
* @param object can be {@literal null}.
* @param links must not be {@literal null}.
* @return
*/
public static <T> RepresentationModel<?> of(@Nullable T object, Iterable<Link> links) {
if (object == null) {
return new RepresentationModel<>(links);
}
if (Collection.class.isInstance(object)) {
return CollectionModel.of((Collection<?>) object, links);
}
return EntityModel.of(object, links);
}
/**

View File

@@ -140,7 +140,7 @@ public class JsonPathLinkDiscoverer implements LinkDiscoverer {
* @return link
*/
protected Link extractLink(Object element, LinkRelation rel) {
return new Link(element.toString(), rel);
return Link.of(element.toString(), rel);
}
/**
@@ -174,7 +174,7 @@ public class JsonPathLinkDiscoverer implements LinkDiscoverer {
return Links.of(Map.class.isInstance(parseResult) //
? extractLink(parseResult, rel) //
: new Link(parseResult.toString(), rel));
: Link.of(parseResult.toString(), rel));
}
private static <T> Optional<T> firstOrEmpty(Iterable<T> source) {

View File

@@ -143,7 +143,7 @@ class Rels {
*/
@Override
public Optional<Link> findInResponse(@Nullable String representation, @Nullable MediaType mediaType) {
return Optional.of(new Link(JsonPath.read(representation, jsonPath).toString(), rel));
return Optional.of(Link.of(JsonPath.read(representation, jsonPath).toString(), rel));
}
}
}

View File

@@ -377,7 +377,7 @@ public class Traverson {
Assert.isTrue(rels.size() > 0, "At least one rel needs to be provided!");
return new Link(expandFinalUrl ? traverseToExpandedFinalUrl().getUri().toString() : traverseToFinalUrl().getUri(),
return Link.of(expandFinalUrl ? traverseToExpandedFinalUrl().getUri().toString() : traverseToFinalUrl().getUri(),
rels.get(rels.size() - 1).getRel());
}

View File

@@ -100,7 +100,7 @@ class CollectionJson<T> {
return this;
}
return withLinks(Links.of(new Link(href)).merge(MergeMode.SKIP_BY_REL, links));
return withLinks(Links.of(Link.of(href)).merge(MergeMode.SKIP_BY_REL, links));
}
boolean hasItems() {

View File

@@ -53,7 +53,7 @@ class CollectionJsonItem<T> {
private @Nullable String href;
private List<CollectionJsonData> data;
private @JsonInclude(Include.NON_EMPTY) Links links;
private @Nullable @Getter(onMethod = @__({ @JsonIgnore }), value = AccessLevel.PRIVATE) T rawData;
private @Nullable @Getter(onMethod = @__(@JsonIgnore)) T rawData;
@JsonCreator
CollectionJsonItem(@JsonProperty("href") @Nullable String href, //
@@ -91,6 +91,10 @@ class CollectionJsonItem<T> {
return Collections.singletonList(new CollectionJsonData().withValue(this.rawData));
}
if (rawData == null) {
return Collections.emptyList();
}
return PropertyUtils.extractPropertyValues(this.rawData).entrySet().stream() //
.map(entry -> new CollectionJsonData() //
.withName(entry.getKey()) //
@@ -135,6 +139,6 @@ class CollectionJsonItem<T> {
return this;
}
return withLinks(Links.of(new Link(href)).merge(MergeMode.SKIP_BY_REL, links));
return withLinks(Links.of(Link.of(href)).merge(MergeMode.SKIP_BY_REL, links));
}
}

View File

@@ -762,7 +762,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule {
Object obj = PropertyUtils.createObjectFromProperties(rootType.getRawClass(), properties);
return new EntityModel<>(obj, links);
return EntityModel.of(obj, links);
} else {
@@ -774,7 +774,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule {
CollectionJsonItem<?> firstItem = items.get(0).withOwnSelfLink();
return new EntityModel<>(firstItem.toRawData(rootType),
return EntityModel.of(firstItem.toRawData(rootType),
merged.merge(MergeMode.REPLACE_BY_REL, firstItem.getLinks()));
}
}
@@ -877,7 +877,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule {
return collection.getItems().stream() //
.map(CollectionJsonItem::withOwnSelfLink) //
.map(it -> isResource //
? new EntityModel<>(it.toRawData(rootType), it.getLinks()) //
? RepresentationModel.of(it.toRawData(rootType), it.getLinks()) //
: it.toRawData(rootType)) //
.collect(Collectors.collectingAndThen(Collectors.toList(), it -> finalizer.apply(it, links)));
}
@@ -902,7 +902,7 @@ public class Jackson2CollectionJsonModule extends SimpleModule {
private static final long serialVersionUID = -7465448422501330790L;
private static final BiFunction<List<Object>, Links, PagedModel<?>> FINISHER = (content,
links) -> new PagedModel<>(content, null, links);
links) -> PagedModel.of(content, null, links);
private static final Function<JavaType, CollectionJsonDeserializerBase<PagedModel<?>>> CONTEXTUAL_CREATOR = CollectionJsonPagedResourcesDeserializer::new;
CollectionJsonPagedResourcesDeserializer() {

View File

@@ -155,6 +155,7 @@ public class DefaultCurieProvider implements CurieProvider {
private final @Getter String name;
@SuppressWarnings("deprecation")
public Curie(String name, String href) {
super(href, "curies");

View File

@@ -57,7 +57,7 @@ public class HalLinkDiscoverer extends JsonPathLinkDiscoverer {
Map<String, String> json = (Map<String, String>) element;
return new Link(json.get("href"), rel) //
return Link.of(json.get("href"), rel) //
.withHreflang(json.get("hreflang")) //
.withMedia(json.get("media")) //
.withTitle(json.get("title")) //

View File

@@ -82,7 +82,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
public class Jackson2HalModule extends SimpleModule {
private static final long serialVersionUID = 7806951456457932384L;
private static final Link CURIES_REQUIRED_DUE_TO_EMBEDS = new Link("__rel__", "¯\\_(ツ)_/¯");
private static final Link CURIES_REQUIRED_DUE_TO_EMBEDS = Link.of("__rel__", "¯\\_(ツ)_/¯");
public Jackson2HalModule() {
@@ -606,12 +606,12 @@ public class Jackson2HalModule extends SimpleModule {
if (JsonToken.START_ARRAY.equals(jp.nextToken())) {
while (!JsonToken.END_ARRAY.equals(jp.nextToken())) {
link = jp.readValueAs(Link.class);
result.add(new Link(link.getHref(), relation).withHreflang(link.getHreflang()).withTitle(link.getTitle())
result.add(Link.of(link.getHref(), relation).withHreflang(link.getHreflang()).withTitle(link.getTitle())
.withType(link.getType()).withDeprecation(link.getDeprecation()));
}
} else {
link = jp.readValueAs(Link.class);
result.add(new Link(link.getHref(), relation).withHreflang(link.getHreflang()).withTitle(link.getTitle())
result.add(Link.of(link.getHref(), relation).withHreflang(link.getHreflang()).withTitle(link.getTitle())
.withType(link.getType()).withDeprecation(link.getDeprecation()));
}
}

View File

@@ -576,7 +576,7 @@ public class Jackson2UberModule extends SimpleModule {
/**
* Custom {@link StdDeserializer} to deserialize {@link EntityModel}.
*/
static class UberEntityModelDeserializer extends ContainerDeserializerBase<EntityModel<?>>
static class UberEntityModelDeserializer extends ContainerDeserializerBase<RepresentationModel<?>>
implements ContextualDeserializer {
private static final long serialVersionUID = 1776321413269082414L;
@@ -599,7 +599,7 @@ public class Jackson2UberModule extends SimpleModule {
*/
@Override
@SuppressWarnings("null")
public EntityModel<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
public RepresentationModel<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
UberDocument doc = p.getCodec().readValue(p, UberDocument.class);
Links links = doc.getUber().getLinks();
@@ -612,8 +612,7 @@ public class Jackson2UberModule extends SimpleModule {
() -> new IllegalStateException("No data entry containing a 'value' was found in this document!"));
}
@NotNull
private EntityModel<Object> convertToResource(UberData uberData, Links links) {
private RepresentationModel<?> convertToResource(UberData uberData, Links links) {
// Primitive type
List<UberData> data = uberData.getData();
@@ -625,9 +624,9 @@ public class Jackson2UberModule extends SimpleModule {
if (isPrimitiveType(data)) {
UberData firstItem = data.get(0);
Object scalarValue = firstItem.getValue();
return new EntityModel<>(scalarValue, links);
return RepresentationModel.of(scalarValue, links);
}
Map<String, Object> properties = data == null //
@@ -637,7 +636,7 @@ public class Jackson2UberModule extends SimpleModule {
JavaType rootType = JacksonHelper.findRootType(this.contentType);
Object value = PropertyUtils.createObjectFromProperties(rootType.getRawClass(), properties);
return new EntityModel<>(value, links);
return EntityModel.of(value, links);
}
/*
@@ -774,7 +773,7 @@ public class Jackson2UberModule extends SimpleModule {
CollectionModel<?> resources = extractResources(doc, rootType, this.contentType);
PageMetadata pageMetadata = extractPagingMetadata(doc);
return new PagedModel<>(resources.getContent(), pageMetadata, resources.getLinks());
return PagedModel.of(resources.getContent(), pageMetadata, resources.getLinks());
}
/**
@@ -834,7 +833,7 @@ public class Jackson2UberModule extends SimpleModule {
}
List<Link> resourceLinks = new ArrayList<>();
EntityModel<?> resource = null;
RepresentationModel<?> resource = null;
List<UberData> data = uberData.getData();
@@ -861,7 +860,8 @@ public class Jackson2UberModule extends SimpleModule {
UberData firstItem = itemData.get(0);
Object scalarValue = firstItem.getValue();
resource = new EntityModel<>(scalarValue, uberData.getLinks());
resource = RepresentationModel.of(scalarValue, uberData.getLinks());
} else {
@@ -871,7 +871,7 @@ public class Jackson2UberModule extends SimpleModule {
.collect(Collectors.toMap(UberData::getName, UberData::getValue));
Object obj = PropertyUtils.createObjectFromProperties(rootType.getRawClass(), properties);
resource = new EntityModel<>(obj, uberData.getLinks());
resource = EntityModel.of(obj, uberData.getLinks());
}
}
}
@@ -889,7 +889,7 @@ public class Jackson2UberModule extends SimpleModule {
/*
* Either return a Resources<Resource<T>>...
*/
return new CollectionModel<>(content, doc.getUber().getLinks());
return CollectionModel.of(content, doc.getUber().getLinks());
} else {
/*
* ...or return a Resources<T>
@@ -898,7 +898,7 @@ public class Jackson2UberModule extends SimpleModule {
List<Object> resourceLessContent = content.stream().map(item -> (EntityModel<?>) item)
.map(EntityModel::getContent).collect(Collectors.toList());
return new CollectionModel<>(resourceLessContent, doc.getUber().getLinks());
return CollectionModel.of(resourceLessContent, doc.getUber().getLinks());
}
}

View File

@@ -148,7 +148,7 @@ class UberData {
return Optional.ofNullable(this.rel) //
.map(rels -> rels.stream() //
.map(rel -> new Link(url, rel)) //
.map(rel -> Link.of(url, rel)) //
.collect(Collectors.toList())) //
.orElse(Collections.emptyList());
}
@@ -296,7 +296,7 @@ class UberData {
return extractLinksAndContent((RepresentationModel<?>) item);
}
return extractLinksAndContent(new EntityModel<>(item));
return extractLinksAndContent(EntityModel.of(item));
}
/**
@@ -374,11 +374,11 @@ class UberData {
return affordanceBasedLinks.stream() //
.flatMap(affordance -> links.stream() //
.filter(data -> data.hasUrl(affordance.getUrl())) //
.map(link -> {
.map(data -> {
if (link.getAction() == affordance.getAction()) {
if (data.getAction() == affordance.getAction()) {
List<LinkRelation> rels = new ArrayList<>(link.getRel());
List<LinkRelation> rels = new ArrayList<>(data.getRel());
rels.addAll(affordance.getRel());
return affordance.withName(rels.get(0).value()) //

View File

@@ -30,6 +30,7 @@ import org.springframework.hateoas.Link;
import org.springframework.hateoas.Links;
import org.springframework.hateoas.RepresentationModel;
import org.springframework.hateoas.server.core.Relation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -45,11 +46,12 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
* @see https://github.com/blongden/vnd.error
* @author Oliver Gierke
* @author Greg Turnquist
* @deprecated Use {@link org.springframework.hateoas.mediatype.problem.Problem} to form vendor neutral error messages.
* @deprecated since 1.1, use {@link org.springframework.hateoas.mediatype.problem.Problem} to form vendor neutral error
* messages.
*/
@JsonPropertyOrder({ "message", "logref", "total", "_links", "_embedded" })
@JsonIgnoreProperties(ignoreUnknown = true)
@EqualsAndHashCode
@EqualsAndHashCode(callSuper = true)
@Deprecated
public class VndErrors extends CollectionModel<VndErrors.VndError> {
@@ -177,8 +179,16 @@ public class VndErrors extends CollectionModel<VndErrors.VndError> {
/**
* Virtual attribute to generate JSON field of {@literal total}. Only generated when there are multiple errors.
*/
@Nullable
@JsonInclude(JsonInclude.Include.NON_NULL)
public Integer getTotal() {
List<VndError> errors = this.errors;
if (errors == null) {
return null;
}
return this.errors.size() > 1 //
? this.errors.size() //
: null; //
@@ -214,12 +224,12 @@ public class VndErrors extends CollectionModel<VndErrors.VndError> {
*
* @author Oliver Gierke
* @author Greg Turnquist
*
* @deprecated Use {@link org.springframework.hateoas.mediatype.problem.Problem} to form vendor neutral error messages.
* @deprecated Use {@link org.springframework.hateoas.mediatype.problem.Problem} to form vendor neutral error
* messages.
*/
@JsonPropertyOrder({ "message", "path", "logref" })
@Relation(collectionRelation = "errors")
@EqualsAndHashCode
@EqualsAndHashCode(callSuper = true)
@Deprecated
public static class VndError extends RepresentationModel<VndError> {

View File

@@ -29,8 +29,7 @@ import org.springframework.util.Assert;
* @author Greg Turnquist
* @since 1.0
*/
public interface SimpleRepresentationModelAssembler<T>
extends RepresentationModelAssembler<T, EntityModel<T>> {
public interface SimpleRepresentationModelAssembler<T> extends RepresentationModelAssembler<T, EntityModel<T>> {
/**
* Converts the given entity into a {@link EntityModel}.
@@ -40,7 +39,7 @@ public interface SimpleRepresentationModelAssembler<T>
*/
default EntityModel<T> toModel(T entity) {
EntityModel<T> resource = new EntityModel<>(entity);
EntityModel<T> resource = EntityModel.of(entity);
addLinks(resource);
return resource;
}
@@ -60,8 +59,7 @@ public interface SimpleRepresentationModelAssembler<T>
* @return {@link CollectionModel} containing {@link EntityModel} of {@code T}.
*/
@Override
default CollectionModel<EntityModel<T>> toCollectionModel(
Iterable<? extends T> entities) {
default CollectionModel<EntityModel<T>> toCollectionModel(Iterable<? extends T> entities) {
Assert.notNull(entities, "entities must not be null!");
List<EntityModel<T>> resourceList = new ArrayList<>();
@@ -70,8 +68,7 @@ public interface SimpleRepresentationModelAssembler<T>
resourceList.add(toModel(entity));
}
CollectionModel<EntityModel<T>> resources = new CollectionModel<>(
resourceList);
CollectionModel<EntityModel<T>> resources = CollectionModel.of(resourceList);
addLinks(resources);
return resources;
}

View File

@@ -139,7 +139,7 @@ public abstract class LinkBuilderSupport<T extends LinkBuilder> implements LinkB
*/
public Link withRel(LinkRelation rel) {
return new Link(toString(), rel) //
return Link.of(toString(), rel) //
.withAffordances(affordances);
}

View File

@@ -50,7 +50,7 @@ public class SpringAffordanceBuilder {
public static List<Affordance> create(Class<?> type, Method method, String href, MappingDiscoverer discoverer) {
String methodName = method.getName();
Link affordanceLink = new Link(href, LinkRelation.of(methodName));
Link affordanceLink = Link.of(href, LinkRelation.of(methodName));
MethodParameters parameters = MethodParameters.of(method);

View File

@@ -161,7 +161,7 @@ public abstract class RepresentationModelAssemblerSupport<T, D extends Represent
* @return
*/
public CollectionModel<D> toResources() {
return new CollectionModel<>(toListOfResources());
return CollectionModel.of(toListOfResources());
}
}
}

View File

@@ -1,5 +1,5 @@
/**
* Spring MVC helper classes to build {@link org.springframework.hateoas.Link}s and assemble
* Spring MVC helper classes to build {@link org.springframework.hateoas.Link}s and assemble
* {@link org.springframework.hateoas.RepresentationModel} types.
*/
@NonNullApi

View File

@@ -42,7 +42,7 @@ public interface SimpleReactiveRepresentationModelAssembler<T>
@Override
default Mono<EntityModel<T>> toModel(T entity, ServerWebExchange exchange) {
EntityModel<T> resource = new EntityModel<>(entity);
EntityModel<T> resource = EntityModel.of(entity);
return Mono.just(addLinks(resource, exchange));
}