mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
DS-3483 add support to embed linked resources collection in the HAL document
This is an initial draft that require further refinements. By default now all the collection properties are embedded in response, linked entities listed in the LinksRest annotation of the repository are included only if specified in the resource wrapper instantiation and supported for embedding by the link repository (i.e the relation have suitable default or don't depend on additional parameters)
This commit is contained in:
@@ -27,6 +27,7 @@ import org.dspace.app.rest.model.LinkRest;
|
||||
import org.dspace.app.rest.model.LinksRest;
|
||||
import org.dspace.app.rest.model.RestModel;
|
||||
import org.dspace.app.rest.model.hateoas.DSpaceResource;
|
||||
import org.dspace.app.rest.model.hateoas.EmbeddedPage;
|
||||
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
||||
import org.dspace.app.rest.repository.LinkRestRepository;
|
||||
import org.dspace.app.rest.utils.Utils;
|
||||
@@ -175,9 +176,26 @@ public class RestResourceController implements InitializingBean {
|
||||
//TODO create a custom exception
|
||||
throw new ResourceNotFoundException(rel + "undefined for "+ model);
|
||||
}
|
||||
|
||||
ResourceSupport resu = (ResourceSupport) result.getEmbedded().get(rel);
|
||||
return resu;
|
||||
else if (result.getEmbedded().get(rel) instanceof EmbeddedPage){
|
||||
// this is a very inefficient scenario. We have an embedded list
|
||||
// already fully retrieved that we need to limit with pagination
|
||||
// parameter. BTW change the default sorting is not implemented at
|
||||
// the current stage and could be overcompex to implement
|
||||
// if we really want to implement pagination we should implement a
|
||||
// link repository so to fall in the previous block code
|
||||
EmbeddedPage ep = (EmbeddedPage) result.getEmbedded().get(rel);
|
||||
List<? extends RestModel> fullList = ep.getFullList();
|
||||
if (fullList == null || fullList.size() == 0) return null;
|
||||
int start = page.getOffset();
|
||||
int end = (start + page.getPageSize()) > fullList.size() ? fullList.size() : (start + page.getPageSize());
|
||||
DSpaceRestRepository<RestModel, ?> resourceRepository = utils.getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType());
|
||||
PageImpl<RestModel> pageResult = new PageImpl(fullList.subList(start, end), page, fullList.size());
|
||||
return assembler.toResource(pageResult .map(resourceRepository::wrapResource));
|
||||
}
|
||||
else {
|
||||
ResourceSupport resu = (ResourceSupport) result.getEmbedded().get(rel);
|
||||
return resu;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
|
@@ -11,6 +11,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||
|
||||
/**
|
||||
* The Item REST Resource
|
||||
@@ -79,6 +81,9 @@ public class ItemRest extends DSpaceObjectRest {
|
||||
public void setTemplateItemOf(CollectionRest templateItemOf){
|
||||
this.templateItemOf = templateItemOf;
|
||||
}
|
||||
|
||||
@LinkRest(linkClass = BitstreamRest.class)
|
||||
@JsonIgnore
|
||||
public List<BitstreamRest> getBitstreams() {
|
||||
return bitstreams;
|
||||
}
|
||||
|
@@ -18,12 +18,12 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.FIELD})
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface LinkRest {
|
||||
String name();
|
||||
String method();
|
||||
String name() default "";
|
||||
String method() default "";
|
||||
Class linkClass();
|
||||
boolean optional() default false;
|
||||
}
|
||||
|
@@ -21,6 +21,10 @@ import org.dspace.app.rest.utils.Utils;
|
||||
public class BrowseIndexResource extends DSpaceResource<BrowseIndexRest> {
|
||||
public BrowseIndexResource(BrowseIndexRest bix, Utils utils, String... rels) {
|
||||
super(bix, utils, rels);
|
||||
// TODO: the following code will force the embedding of items and
|
||||
// entries in the browseIndex we need to find a way to populate the rels
|
||||
// array from the request/projection right now it is always null
|
||||
// super(bix, utils, "items", "entries");
|
||||
if (bix.isMetadataBrowse()) {
|
||||
add(utils.linkToSubResource(bix, BrowseIndexRest.ENTRIES));
|
||||
}
|
||||
|
@@ -7,18 +7,38 @@
|
||||
*/
|
||||
package org.dspace.app.rest.model.hateoas;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.atteo.evo.inflector.English;
|
||||
import org.dspace.app.rest.model.BaseObjectRest;
|
||||
import org.dspace.app.rest.model.LinkRest;
|
||||
import org.dspace.app.rest.model.LinksRest;
|
||||
import org.dspace.app.rest.model.RestModel;
|
||||
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
||||
import org.dspace.app.rest.repository.LinkRestRepository;
|
||||
import org.dspace.app.rest.utils.Utils;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.PagedResources;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.core.EmbeddedWrappers;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@@ -47,18 +67,131 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
|
||||
|
||||
if (data != null) {
|
||||
try {
|
||||
LinksRest links = data.getClass().getDeclaredAnnotation(LinksRest.class);
|
||||
if (links != null && rels != null) {
|
||||
List<String> relsList = Arrays.asList(rels);
|
||||
for (LinkRest linkAnnotation : links.links()) {
|
||||
if (!relsList.contains(linkAnnotation.name())) {
|
||||
continue;
|
||||
}
|
||||
String name = linkAnnotation.name();
|
||||
Link linkToSubResource = utils.linkToSubResource(data, name);
|
||||
String apiCategory = data.getCategory();
|
||||
String model = data.getType();
|
||||
LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkAnnotation.name());
|
||||
|
||||
if (!linkRepository.isEmbbeddableRelation(data, linkAnnotation.name())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
//RestModel linkClass = linkAnnotation.linkClass().newInstance();
|
||||
Method[] methods = linkRepository.getClass().getMethods();
|
||||
boolean found = false;
|
||||
for (Method m : methods) {
|
||||
if (StringUtils.equals(m.getName(), linkAnnotation.method())) {
|
||||
// TODO add support for single linked object other than for collections
|
||||
Page<? extends Serializable> pageResult = (Page<? extends RestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null);
|
||||
EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null);
|
||||
embedded.put(name, ep);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
// TODO custom exception
|
||||
if (!found) {
|
||||
throw new RuntimeException("Method for relation " + linkAnnotation.name() + " not found: " + linkAnnotation.method());
|
||||
}
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PropertyDescriptor pd : Introspector.getBeanInfo(data.getClass()).getPropertyDescriptors()) {
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null && !"class".equals(pd.getName())) {
|
||||
if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) {
|
||||
this.add(utils.linkToSubResource(data, pd.getName()));
|
||||
String name = pd.getName();
|
||||
if (readMethod != null && !"class".equals(name)) {
|
||||
LinkRest linkAnnotation = readMethod.getAnnotation(LinkRest.class);
|
||||
|
||||
if (linkAnnotation != null) {
|
||||
if (StringUtils.isNotBlank(linkAnnotation.name())) {
|
||||
name = linkAnnotation.name();
|
||||
}
|
||||
Link linkToSubResource = utils.linkToSubResource(data, name);
|
||||
// no method is specified to retrieve the linked object(s) so check if it is already here
|
||||
if (StringUtils.isBlank(linkAnnotation.method())) {
|
||||
this.add(linkToSubResource);
|
||||
Object linkedObject = readMethod.invoke(data);
|
||||
Object wrapObject = linkedObject;
|
||||
if (linkedObject instanceof RestModel) {
|
||||
RestModel linkedRM = (RestModel) linkedObject;
|
||||
wrapObject = utils.getResourceRepository(linkedRM.getCategory(), linkedRM.getType())
|
||||
.wrapResource(linkedRM);
|
||||
}
|
||||
else {
|
||||
if (linkedObject instanceof List) {
|
||||
List<RestModel> linkedRMList = (List<RestModel>) linkedObject;
|
||||
if (linkedRMList.size() > 0) {
|
||||
|
||||
DSpaceRestRepository<RestModel, ?> resourceRepository = utils.getResourceRepository(linkedRMList.get(0).getCategory(), linkedRMList.get(0).getType());
|
||||
// TODO should we force pagination also of embedded resource?
|
||||
// This will force a pagination with size 10 for embedded collections as well
|
||||
// int pageSize = 1;
|
||||
// PageImpl<RestModel> page = new PageImpl(
|
||||
// linkedRMList.subList(0,
|
||||
// linkedRMList.size() > pageSize ? pageSize : linkedRMList.size()), new PageRequest(0, pageSize), linkedRMList.size());
|
||||
PageImpl<RestModel> page = new PageImpl(linkedRMList);
|
||||
wrapObject = new EmbeddedPage(linkToSubResource.getHref(), page.map(resourceRepository::wrapResource), linkedRMList);
|
||||
}
|
||||
else {
|
||||
wrapObject = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (linkedObject != null) {
|
||||
embedded.put(name, wrapObject);
|
||||
} else {
|
||||
embedded.put(name, null);
|
||||
}
|
||||
Method writeMethod = pd.getWriteMethod();
|
||||
writeMethod.invoke(data, new Object[] { null });
|
||||
}
|
||||
else {
|
||||
// call the link repository
|
||||
try {
|
||||
//RestModel linkClass = linkAnnotation.linkClass().newInstance();
|
||||
String apiCategory = data.getCategory();
|
||||
String model = data.getType();
|
||||
LinkRestRepository linkRepository = utils.getLinkResourceRepository(apiCategory, model, linkAnnotation.name());
|
||||
Method[] methods = linkRepository.getClass().getMethods();
|
||||
boolean found = false;
|
||||
for (Method m : methods) {
|
||||
if (StringUtils.equals(m.getName(), linkAnnotation.method())) {
|
||||
// TODO add support for single linked object other than for collections
|
||||
Page<? extends Serializable> pageResult = (Page<? extends RestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null);
|
||||
EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null);
|
||||
embedded.put(name, ep);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
// TODO custom exception
|
||||
if (!found) {
|
||||
throw new RuntimeException("Method for relation " + linkAnnotation.name() + " not found: " + linkAnnotation.method());
|
||||
}
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) {
|
||||
Link linkToSubResource = utils.linkToSubResource(data, name);
|
||||
this.add(linkToSubResource);
|
||||
RestModel linkedObject = (RestModel) readMethod.invoke(data);
|
||||
if (linkedObject != null) {
|
||||
embedded.put(pd.getName(),
|
||||
embedded.put(name,
|
||||
utils.getResourceRepository(linkedObject.getCategory(), linkedObject.getType())
|
||||
.wrapResource(linkedObject));
|
||||
} else {
|
||||
embedded.put(pd.getName(), null);
|
||||
embedded.put(name, null);
|
||||
}
|
||||
|
||||
Method writeMethod = pd.getWriteMethod();
|
||||
@@ -74,6 +207,11 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Link link) {
|
||||
System.out.println("Chiamato "+link.getRel());
|
||||
super.add(link);
|
||||
}
|
||||
public Map<String, Object> getEmbedded() {
|
||||
return embedded;
|
||||
}
|
||||
|
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest.model.hateoas;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class EmbeddedPage {
|
||||
|
||||
private Page page;
|
||||
private List fullList;
|
||||
private UriComponentsBuilder self;
|
||||
|
||||
public EmbeddedPage(String self, Page page, List fullList) {
|
||||
this.page = page;
|
||||
this.fullList = fullList;
|
||||
this.self = UriComponentsBuilder.fromUriString(self);
|
||||
}
|
||||
|
||||
@JsonProperty(value = "_embedded")
|
||||
public List getPageContent() {
|
||||
return page.getContent();
|
||||
}
|
||||
|
||||
@JsonProperty(value = "page")
|
||||
public Map<String, Long> getPageInfo() {
|
||||
Map<String, Long> pageInfo = new HashMap<String, Long>();
|
||||
pageInfo.put("number", (long) page.getNumber());
|
||||
pageInfo.put("size", (long) page.getSize() != 0?page.getSize():page.getTotalElements());
|
||||
pageInfo.put("totalPages", (long) page.getTotalPages());
|
||||
pageInfo.put("totalElements", page.getTotalElements());
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
@JsonProperty(value = "_links")
|
||||
public Map<String, String> getLinks() {
|
||||
Map<String, String> links = new HashMap<String, String>();
|
||||
if (!page.isFirst()) {
|
||||
links.put("first", _link(0));
|
||||
links.put("self", _link(page.getNumber()));
|
||||
}
|
||||
else {
|
||||
links.put("self", self.toUriString());
|
||||
}
|
||||
if (!page.isLast()) {
|
||||
links.put("last", _link(page.getTotalPages()-1));
|
||||
}
|
||||
if (page.hasPrevious()) {
|
||||
links.put("prev", _link(page.getNumber()-1));
|
||||
}
|
||||
if (page.hasNext()) {
|
||||
links.put("next", _link(page.getNumber()+1));
|
||||
}
|
||||
return links;
|
||||
}
|
||||
|
||||
private String _link(int i) {
|
||||
UriComponentsBuilder uriComp = self.cloneBuilder();
|
||||
return uriComp.queryParam("page", i).build().toString();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List getFullList() {
|
||||
return fullList;
|
||||
}
|
||||
}
|
@@ -65,7 +65,10 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
|
||||
Pageable pageable, String projection) throws BrowseException, SQLException {
|
||||
// FIXME this should be bind automatically and available as method
|
||||
// argument
|
||||
String scope = request.getParameter("scope");
|
||||
String scope = null;
|
||||
if (request != null) {
|
||||
request.getParameter("scope");
|
||||
}
|
||||
|
||||
Context context = obtainContext();
|
||||
BrowseEngine be = new BrowseEngine(context);
|
||||
@@ -95,7 +98,10 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
|
||||
|
||||
// set up a BrowseScope and start loading the values into it
|
||||
bs.setBrowseIndex(bi);
|
||||
Sort sort = pageable.getSort();
|
||||
Sort sort = null;
|
||||
if (pageable != null) {
|
||||
sort = pageable.getSort();
|
||||
}
|
||||
if (sort != null) {
|
||||
Iterator<Order> orders = sort.iterator();
|
||||
while (orders.hasNext()) {
|
||||
@@ -108,8 +114,10 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
|
||||
// bs.setJumpToValue(valueFocus);
|
||||
// bs.setJumpToValueLang(valueFocusLang);
|
||||
// bs.setStartsWith(startsWith);
|
||||
bs.setOffset(pageable.getOffset());
|
||||
bs.setResultsPerPage(pageable.getPageSize());
|
||||
if (pageable != null) {
|
||||
bs.setOffset(pageable.getOffset());
|
||||
bs.setResultsPerPage(pageable.getPageSize());
|
||||
}
|
||||
// bs.setEtAl(etAl);
|
||||
// bs.setAuthorityValue(authority);
|
||||
|
||||
@@ -119,7 +127,7 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
|
||||
|
||||
BrowseInfo binfo = be.browse(bs);
|
||||
Pageable pageResultInfo = new PageRequest((binfo.getStart() - 1) / binfo.getResultsPerPage(),
|
||||
pageable.getPageSize());
|
||||
binfo.getResultsPerPage());
|
||||
Page<BrowseEntryRest> page = new PageImpl<String[]>(Arrays.asList(binfo.getStringResults()), pageResultInfo,
|
||||
binfo.getTotal()).map(converter);
|
||||
page.forEach(new Consumer<BrowseEntryRest>() {
|
||||
@@ -135,4 +143,13 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
|
||||
public BrowseEntryResource wrapResource(BrowseEntryRest entry, String... rels) {
|
||||
return new BrowseEntryResource(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbbeddableRelation(Object data, String name) {
|
||||
BrowseIndexRest bir = (BrowseIndexRest) data;
|
||||
if (bir.isMetadataBrowse() && "entries".equals(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -63,10 +63,15 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
|
||||
public Page<ItemRest> listBrowseItems(HttpServletRequest request, String browseName, Pageable pageable, String projection)
|
||||
throws BrowseException, SQLException {
|
||||
//FIXME these should be bind automatically and available as method arguments
|
||||
String scope = request.getParameter("scope");
|
||||
String filterValue = request.getParameter("filterValue");
|
||||
String filterAuthority = request.getParameter("filterAuthority");
|
||||
|
||||
String scope = null;
|
||||
String filterValue = null;
|
||||
String filterAuthority = null;
|
||||
|
||||
if (request != null) {
|
||||
scope = request.getParameter("scope");
|
||||
filterValue = request.getParameter("filterValue");
|
||||
filterAuthority = request.getParameter("filterAuthority");
|
||||
}
|
||||
Context context = obtainContext();
|
||||
BrowseEngine be = new BrowseEngine(context);
|
||||
BrowserScope bs = new BrowserScope(context);
|
||||
@@ -97,7 +102,10 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
|
||||
|
||||
// set up a BrowseScope and start loading the values into it
|
||||
bs.setBrowseIndex(bi);
|
||||
Sort sort = pageable.getSort();
|
||||
Sort sort = null;
|
||||
if (pageable != null) {
|
||||
sort = pageable.getSort();
|
||||
}
|
||||
if (sort != null) {
|
||||
Iterator<Order> orders = sort.iterator();
|
||||
while (orders.hasNext()) {
|
||||
@@ -132,9 +140,11 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
|
||||
// bs.setJumpToValue(valueFocus);
|
||||
// bs.setJumpToValueLang(valueFocusLang);
|
||||
// bs.setStartsWith(startsWith);
|
||||
bs.setOffset(pageable.getOffset());
|
||||
bs.setResultsPerPage(pageable.getPageSize());
|
||||
|
||||
if (pageable != null) {
|
||||
bs.setOffset(pageable.getOffset());
|
||||
bs.setResultsPerPage(pageable.getPageSize());
|
||||
}
|
||||
|
||||
if (scopeObj != null) {
|
||||
bs.setBrowseContainer(scopeObj);
|
||||
}
|
||||
@@ -147,7 +157,7 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
|
||||
|
||||
BrowseInfo binfo = be.browse(bs);
|
||||
|
||||
Pageable pageResultInfo = new PageRequest((binfo.getStart() -1) / binfo.getResultsPerPage(), pageable.getPageSize());
|
||||
Pageable pageResultInfo = new PageRequest((binfo.getStart() -1) / binfo.getResultsPerPage(), binfo.getResultsPerPage());
|
||||
Page<ItemRest> page = new PageImpl<Item>(binfo.getBrowseItemResults(), pageResultInfo, binfo.getTotal())
|
||||
.map(converter);
|
||||
return page;
|
||||
@@ -157,4 +167,13 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
|
||||
public ItemResource wrapResource(ItemRest item, String... rels) {
|
||||
return itemRestRepository.wrapResource(item, rels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbbeddableRelation(Object data, String name) {
|
||||
BrowseIndexRest bir = (BrowseIndexRest) data;
|
||||
if (!bir.isMetadataBrowse() && "items".equals(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -19,4 +19,8 @@ import org.springframework.hateoas.ResourceSupport;
|
||||
*/
|
||||
public interface LinkRestRepository<L extends Serializable> {
|
||||
public abstract ResourceSupport wrapResource(L model, String... rels);
|
||||
|
||||
public default boolean isEmbbeddableRelation(Object data, String name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user