#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:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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")) //
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()) //
|
||||
|
||||
@@ -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> {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user