From e0c34e1be657a372f49b0bca738d24821eec0616 Mon Sep 17 00:00:00 2001 From: Jon Brisbin Date: Tue, 12 Mar 2013 13:37:07 -0500 Subject: [PATCH] Fix paging. --- .../AbstractRepositoryRestController.java | 146 ++++++++++++++++++ .../webmvc/RepositoryEntityController.java | 80 +++++----- .../webmvc/RepositoryRestHandlerAdapter.java | 32 ++-- .../webmvc/RepositorySearchController.java | 104 ++++--------- 4 files changed, 224 insertions(+), 138 deletions(-) diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java index e419c834c..52c05f32a 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java @@ -7,8 +7,10 @@ import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import java.util.Locale; +import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,11 +23,17 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.OptimisticLockingFailureException; +import org.springframework.data.domain.Page; +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.config.RepositoryRestConfiguration; import org.springframework.data.rest.config.ResourceMapping; +import org.springframework.data.rest.repository.BaseUriAwareResource; +import org.springframework.data.rest.repository.PagingAndSorting; +import org.springframework.data.rest.repository.PersistentEntityResource; import org.springframework.data.rest.repository.RepositoryConstraintViolationException; import org.springframework.data.rest.repository.invoke.MethodParameterConversionService; import org.springframework.data.rest.repository.support.ResourceMappingUtils; @@ -36,7 +44,9 @@ import org.springframework.data.rest.webmvc.support.ValidationExceptionHandler; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkBuilder; +import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -46,6 +56,7 @@ import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.util.UriComponentsBuilder; /** * @author Jon Brisbin @@ -243,6 +254,56 @@ public class AbstractRepositoryRestController implements ApplicationContextAware return new ResponseEntity>(resource, hdrs, status); } + protected void addQueryParameters(HttpServletRequest request, + UriComponentsBuilder builder) { + for(Enumeration names = request.getParameterNames(); names.hasMoreElements(); ) { + String name = names.nextElement(); + String value = request.getParameter(name); + if(name.equals(config.getPageParamName()) || name.equals(config.getLimitParamName())) { + continue; + } + + builder.queryParam(name, value); + } + } + + protected Link searchLink(RepositoryRestRequest repoRequest, + int pageIncrement, + String method, + String rel) { + PagingAndSorting pageSort = repoRequest.getPagingAndSorting(); + UriComponentsBuilder ucb = UriComponentsBuilder.fromUri( + entityLinks.linkFor(repoRequest.getPersistentEntity().getType()) + .slash("search") + .slash(method) + .toUri() + ); + ucb.queryParam(config.getPageParamName(), Math.max(pageSort.getPageNumber() + pageIncrement, 1)) + .queryParam(config.getLimitParamName(), pageSort.getPageSize()); + + addQueryParameters(repoRequest.getRequest(), ucb); + + return new Link(ucb.build().toString(), rel); + } + + protected Link entitiesPageLink(RepositoryRestRequest repoRequest, + int pageIncrement, + String rel) { + PagingAndSorting pageSort = repoRequest.getPagingAndSorting(); + UriComponentsBuilder ucb = UriComponentsBuilder.fromUri( + entityLinks.linkFor(repoRequest.getPersistentEntity().getType()) + .toUri() + ); + if(null != repoRequest.getRequest().getParameter(config.getPageParamName())) { + ucb.queryParam(config.getPageParamName(), Math.max(pageSort.getPageNumber() + pageIncrement, 1)) + .queryParam(config.getLimitParamName(), pageSort.getPageSize()); + } + + addQueryParameters(repoRequest.getRequest(), ucb); + + return new Link(ucb.build().toString(), rel); + } + protected List queryMethodLinks(URI baseUri, Class domainType) { List links = new ArrayList(); RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(domainType); @@ -269,4 +330,89 @@ public class AbstractRepositoryRestController implements ApplicationContextAware return new Link(selfLink.getHref(), rel); } + @SuppressWarnings({"unchecked"}) + protected ResourceSupport resultToResourceSupport(RepositoryRestRequest repoRequest, + Object result, + List links, + Link prevLink, + Link nextLink) { + ResourceSupport resources; + if(result instanceof Page) { + Page page = (Page)result; + PagedResources.PageMetadata pageMeta = pageMetadata(page); + if(page.hasPreviousPage() && null != prevLink) { + links.add(prevLink); + } + if(page.hasNextPage() && null != nextLink) { + links.add(nextLink); + } + if(page.hasContent()) { + resources = entitiesToResource(repoRequest, page); + } else { + resources = new PagedResources(Collections.emptyList(), pageMeta); + } + } else if(result instanceof Iterable) { + resources = entitiesToResource(repoRequest, (Iterable)result); + } else if(null == result) { + resources = new Resources(EMPTY_RESOURCE_LIST); + } else { + PersistentEntityResource per = PersistentEntityResource.wrap(repoRequest.getPersistentEntity(), + result, + repoRequest.getBaseUri()); + BeanWrapper wrapper = BeanWrapper.create(result, conversionService); + Link selfLink = entityLinks.linkForSingleResource(result.getClass(), + wrapper.getProperty(repoRequest.getPersistentEntity() + .getIdProperty())) + .withSelfRel(); + per.add(selfLink); + resources = per; + } + resources.add(links); + return resources; + } + + @SuppressWarnings({"unchecked"}) + protected ResourceSupport entitiesToResource(RepositoryRestRequest repoRequest, Page page) { + PagedResources.PageMetadata pageMeta = pageMetadata(page); + Resources resource = (Resources)entitiesToResource(repoRequest, page.getContent()); + return new PagedResources(resource.getContent(), pageMeta, resource.getLinks()); + } + + @SuppressWarnings({"unchecked"}) + protected ResourceSupport entitiesToResource(RepositoryRestRequest repoRequest, Iterable entities) { + List> resources = new ArrayList>(); + for(Object obj : entities) { + if(null == obj) { + resources.add(null); + continue; + } + + PersistentEntity persistentEntity = repositories.getPersistentEntity(obj.getClass()); + if(null == persistentEntity) { + resources.add(new BaseUriAwareResource(obj) + .setBaseUri(repoRequest.getBaseUri())); + continue; + } + + BeanWrapper wrapper = BeanWrapper.create(obj, conversionService); + PersistentEntityResource per = PersistentEntityResource.wrap(persistentEntity, obj, repoRequest.getBaseUri()); + Link selfLink = entityLinks.linkForSingleResource(persistentEntity.getType(), + wrapper.getProperty(persistentEntity.getIdProperty())) + .withSelfRel(); + per.add(selfLink); + resources.add(per); + } + + return new Resources(resources); + } + + protected PagedResources.PageMetadata pageMetadata(Page page) { + return new PagedResources.PageMetadata( + page.getNumberOfElements(), + page.getNumber() + 1, + page.getTotalElements(), + page.getTotalPages() + ); + } + } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java index d1c5041d1..77b477885 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java @@ -1,15 +1,15 @@ package org.springframework.data.rest.webmvc; -import static org.springframework.data.rest.core.util.UriUtils.*; - import java.io.Serializable; import java.net.URI; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.BeanWrapper; @@ -17,7 +17,7 @@ import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.config.RepositoryRestConfiguration; import org.springframework.data.rest.config.ResourceMapping; -import org.springframework.data.rest.repository.PageableResources; +import org.springframework.data.rest.repository.PagingAndSorting; import org.springframework.data.rest.repository.PersistentEntityResource; import org.springframework.data.rest.repository.context.AfterCreateEvent; import org.springframework.data.rest.repository.context.AfterDeleteEvent; @@ -31,7 +31,9 @@ import org.springframework.data.rest.repository.json.PersistentEntityToJsonSchem import org.springframework.data.rest.repository.support.DomainObjectMerger; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; +import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -87,9 +89,8 @@ public class RepositoryEntityController extends AbstractRepositoryRestController } ) @ResponseBody - public Resources> listEntities(final RepositoryRestRequest repoRequest) + public ResourceSupport listEntities(final RepositoryRestRequest repoRequest) throws ResourceNotFoundException { - List> resources = new ArrayList>(); List links = new ArrayList(); Iterable results; @@ -100,9 +101,10 @@ public class RepositoryEntityController extends AbstractRepositoryRestController boolean hasPagingParams = (null != repoRequest.getRequest().getParameter(config.getPageParamName())); boolean hasSortParams = (null != repoRequest.getRequest().getParameter(config.getSortParamName())); if(repoMethodInvoker.hasFindAllPageable() && hasPagingParams) { - results = repoMethodInvoker.findAll(new PageRequest(repoRequest.getPagingAndSorting().getPageNumber(), - repoRequest.getPagingAndSorting().getPageSize(), - repoRequest.getPagingAndSorting().getSort())); + PagingAndSorting pageSort = repoRequest.getPagingAndSorting(); + results = repoMethodInvoker.findAll(new PageRequest(pageSort.getPageNumber(), + pageSort.getPageSize(), + pageSort.getSort())); } else if(repoMethodInvoker.hasFindAllSorted() && hasSortParams) { results = repoMethodInvoker.findAll(repoRequest.getPagingAndSorting().getSort()); } else if(repoMethodInvoker.hasFindAll()) { @@ -111,37 +113,25 @@ public class RepositoryEntityController extends AbstractRepositoryRestController throw new ResourceNotFoundException(); } - for(Object o : results) { - BeanWrapper wrapper = BeanWrapper.create(o, conversionService); - Link selfLink = entityLinks.linkForSingleResource(repoRequest.getPersistentEntity().getType(), - wrapper.getProperty(repoRequest.getPersistentEntity() - .getIdProperty())) - .withSelfRel(); - resources.add(new PersistentEntityResource(repoRequest.getPersistentEntity(), - o, - selfLink) - .setBaseUri(repoRequest.getBaseUri())); - } - - + ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping(); if(!repoMethodInvoker.getQueryMethods().isEmpty()) { - ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping(); - links.add(new Link(buildUri(repoRequest.getBaseUri(), repoMapping.getPath(), "search").toString(), - repoMapping.getRel() + ".search")); + links.add(entityLinks.linkForSingleResource(repoRequest.getPersistentEntity().getType(), "search") + .withRel(repoMapping.getRel() + ".search")); } - if(hasPagingParams || hasSortParams) { - PageRequest pr = new PageRequest(repoRequest.getPagingAndSorting().getPageNumber() + 1, - repoRequest.getPagingAndSorting().getPageSize(), - repoRequest.getPagingAndSorting().getSort()) { - @Override public int getOffset() { - return super.getOffset() - repoRequest.getPagingAndSorting().getPageSize(); - } - }; - return new PageableResources>(resources, pr, links); - } else { - return new Resources>(resources, links); + PagingAndSorting pageSort = repoRequest.getPagingAndSorting(); + Link prevLink = null; + Link nextLink = null; + if(results instanceof Page) { + if(((Page)results).hasPreviousPage() && pageSort.getPageNumber() > 0) { + prevLink = entitiesPageLink(repoRequest, 0, "page.previous"); + } + if(((Page)results).hasNextPage()) { + nextLink = entitiesPageLink(repoRequest, 1, "page.next"); + } } + + return resultToResourceSupport(repoRequest, results, links, prevLink, nextLink); } @SuppressWarnings({"unchecked"}) @@ -153,22 +143,22 @@ public class RepositoryEntityController extends AbstractRepositoryRestController } ) @ResponseBody - public Resources> listEntitiesCompact(RepositoryRestRequest repoRequest) + public ResourceSupport listEntitiesCompact(final RepositoryRestRequest repoRequest) throws ResourceNotFoundException { - Resources> resources = listEntities(repoRequest); + ResourceSupport resources = listEntities(repoRequest); List links = new ArrayList(resources.getLinks()); - for(Resource resource : resources.getContent()) { - PersistentEntityResource persistentEntityResource = (PersistentEntityResource)resource; - links.add(resourceLink(repoRequest, persistentEntityResource)); + if(resources instanceof Resources) { + for(Resource resource : ((Resources>)resources).getContent()) { + PersistentEntityResource persistentEntityResource = (PersistentEntityResource)resource; + links.add(resourceLink(repoRequest, persistentEntityResource)); + } } - boolean hasPagingParams = (null != repoRequest.getRequest().getParameter(config.getPageParamName())); - boolean hasSortParams = (null != repoRequest.getRequest().getParameter(config.getSortParamName())); - if(hasPagingParams || hasSortParams) { - return new PageableResources>(EMPTY_RESOURCE_LIST, repoRequest.getPagingAndSorting(), links); + if(resources instanceof PagedResources) { + return new PagedResources(Collections.emptyList(), ((PagedResources)resources).getMetadata(), links); } else { - return new Resources>(EMPTY_RESOURCE_LIST, links); + return new Resources(Collections.emptyList(), links); } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerAdapter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerAdapter.java index 03e251bf9..ce8be574d 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerAdapter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerAdapter.java @@ -18,24 +18,24 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl */ public class RepositoryRestHandlerAdapter extends ResourceProcessorInvokingHandlerAdapter { - @Autowired - private List argumentResolvers; + @Autowired + private List argumentResolvers; - @Override public void afterPropertiesSet() { - setCustomArgumentResolvers(argumentResolvers); - super.afterPropertiesSet(); - } + @Override public void afterPropertiesSet() { + setCustomArgumentResolvers(argumentResolvers); + super.afterPropertiesSet(); + } - @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } + @Override public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } - @Override protected boolean supportsInternal(HandlerMethod handlerMethod) { - Class controllerType = handlerMethod.getBeanType(); - return (RepositoryController.class.isAssignableFrom(controllerType) - || RepositoryEntityController.class.isAssignableFrom(controllerType) - || RepositoryPropertyReferenceController.class.isAssignableFrom(controllerType) - || RepositorySearchController.class.isAssignableFrom(controllerType)); - } + @Override protected boolean supportsInternal(HandlerMethod handlerMethod) { + Class controllerType = handlerMethod.getBeanType(); + return (RepositoryController.class.isAssignableFrom(controllerType) + || RepositoryEntityController.class.isAssignableFrom(controllerType) + || RepositoryPropertyReferenceController.class.isAssignableFrom(controllerType) + || RepositorySearchController.class.isAssignableFrom(controllerType)); + } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java index 69393db9b..5addea431 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java @@ -12,19 +12,18 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.config.RepositoryRestConfiguration; import org.springframework.data.rest.config.ResourceMapping; -import org.springframework.data.rest.repository.BaseUriAwareResource; -import org.springframework.data.rest.repository.PersistentEntityResource; +import org.springframework.data.rest.repository.PagingAndSorting; import org.springframework.data.rest.repository.invoke.RepositoryMethod; import org.springframework.data.rest.repository.invoke.RepositoryMethodInvoker; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; +import org.springframework.hateoas.Resources; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -75,8 +74,9 @@ public class RepositorySearchController extends AbstractRepositoryRestController } ) @ResponseBody - public Resource query(RepositoryRestRequest repoRequest, - @PathVariable String method) + public ResourceSupport query(final RepositoryRestRequest repoRequest, + @PathVariable String repository, + @PathVariable String method) throws ResourceNotFoundException { RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker(); if(repoMethodInvoker.getQueryMethods().isEmpty()) { @@ -99,17 +99,18 @@ public class RepositorySearchController extends AbstractRepositoryRestController } } + PagingAndSorting pageSort = repoRequest.getPagingAndSorting(); List methodParams = repoMethod.getParameters(); Object[] paramValues = new Object[methodParams.size()]; if(!methodParams.isEmpty()) { for(int i = 0; i < paramValues.length; i++) { MethodParameter param = methodParams.get(i); if(Pageable.class.isAssignableFrom(param.getParameterType())) { - paramValues[i] = new PageRequest(repoRequest.getPagingAndSorting().getPageNumber(), - repoRequest.getPagingAndSorting().getPageSize(), - repoRequest.getPagingAndSorting().getSort()); + paramValues[i] = new PageRequest(pageSort.getPageNumber(), + pageSort.getPageSize(), + pageSort.getSort()); } else if(Sort.class.isAssignableFrom(param.getParameterType())) { - paramValues[i] = repoRequest.getPagingAndSorting().getSort(); + paramValues[i] = pageSort.getSort(); } else { String paramName = repoMethod.getParameterNames().get(i); String[] queryParamVals = repoRequest.getRequest().getParameterValues(paramName); @@ -129,42 +130,18 @@ public class RepositorySearchController extends AbstractRepositoryRestController } } - BaseUriAwareResource resources; - List links = new ArrayList(); Object result = repoMethodInvoker.invokeQueryMethod(repoMethod, paramValues); + Link prevLink = null; + Link nextLink = null; if(result instanceof Page) { - Page page = (Page)result; - if(page.hasPreviousPage()) { - repoRequest.addPrevLink(page, links); + if(((Page)result).hasPreviousPage() && pageSort.getPageNumber() > 0) { + prevLink = searchLink(repoRequest, 0, method, "page.previous"); } - if(page.hasNextPage()) { - repoRequest.addNextLink(page, links); + if(((Page)result).hasNextPage()) { + nextLink = searchLink(repoRequest, 1, method, "page.next"); } - if(page.hasContent()) { - resources = entitiesToResource(repoRequest, page.getContent()); - } else { - resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST); - } - } else if(result instanceof Iterable) { - resources = entitiesToResource(repoRequest, (Iterable)result); - } else if(null == result) { - resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST); - } else { - PersistentEntityResource per = PersistentEntityResource.wrap(repoRequest.getPersistentEntity(), - result, - repoRequest.getBaseUri()); - BeanWrapper wrapper = BeanWrapper.create(result, conversionService); - Link selfLink = entityLinks.linkForSingleResource(result.getClass(), - wrapper.getProperty(repoRequest.getPersistentEntity() - .getIdProperty())) - .withSelfRel(); - per.add(selfLink); - resources = per; } - resources.setBaseUri(repoRequest.getBaseUri()) - .add(links); - - return resources; + return resultToResourceSupport(repoRequest, result, new ArrayList(), prevLink, nextLink); } @RequestMapping( @@ -175,56 +152,29 @@ public class RepositorySearchController extends AbstractRepositoryRestController } ) @ResponseBody - public Resource queryCompact(RepositoryRestRequest repoRequest, - @PathVariable String method) + public ResourceSupport queryCompact(RepositoryRestRequest repoRequest, + @PathVariable String repository, + @PathVariable String method) throws ResourceNotFoundException { List links = new ArrayList(); - Resource resource = query(repoRequest, method); + ResourceSupport resource = query(repoRequest, repository, method); links.addAll(resource.getLinks()); - if(resource.getContent() instanceof Iterable) { - Iterable iter = (Iterable)resource.getContent(); - for(Object obj : iter) { + if(resource instanceof Resources && ((Resources)resource).getContent() != null) { + for(Object obj : ((Resources)resource).getContent()) { if(null != obj && obj instanceof Resource) { Resource res = (Resource)obj; links.add(resourceLink(repoRequest, res)); } } - } else if(resource.getContent() instanceof Resource) { - Resource res = (Resource)resource.getContent(); + } else if(resource instanceof Resource) { + Resource res = (Resource)resource; links.add(resourceLink(repoRequest, res)); } + return new Resource(EMPTY_RESOURCE_LIST, links); } - @SuppressWarnings({"unchecked"}) - private BaseUriAwareResource entitiesToResource(RepositoryRestRequest repoRequest, Iterable entities) { - List> resources = new ArrayList>(); - for(Object obj : entities) { - if(null == obj) { - resources.add(null); - break; - } - - PersistentEntity persistentEntity = repositories.getPersistentEntity(obj.getClass()); - if(null == persistentEntity) { - resources.add(new BaseUriAwareResource(obj) - .setBaseUri(repoRequest.getBaseUri())); - continue; - } - - BeanWrapper wrapper = BeanWrapper.create(obj, conversionService); - PersistentEntityResource per = PersistentEntityResource.wrap(persistentEntity, obj, repoRequest.getBaseUri()); - Link selfLink = entityLinks.linkForSingleResource(persistentEntity.getType(), - wrapper.getProperty(persistentEntity.getIdProperty())) - .withSelfRel(); - per.add(selfLink); - resources.add(per); - } - return new BaseUriAwareResource(resources) - .setBaseUri(repoRequest.getBaseUri()); - } - }