From e6efe5ea261a4a3830ab3f46285d485092119258 Mon Sep 17 00:00:00 2001 From: Thomas Pasch Date: Sat, 9 Nov 2019 20:39:45 +0100 Subject: [PATCH 1/3] pageable in app2 (cherry picked from commit ad4bbc7259ad70f074928ca9d6ae387ee19c09a6) --- .../org/springdoc/demo/app2/api/PetApi.java | 11 +++++ .../demo/app2/api/PetApiDelegate.java | 6 +++ .../demo/app2/api/PetApiDelegateImpl.java | 7 ++++ .../app2/repository/HashMapRepository.java | 42 +++++++++++++++++++ .../demo/app2/repository/OrderRepository.java | 4 ++ .../demo/app2/repository/PetRepository.java | 4 ++ .../demo/app2/repository/UserRepository.java | 4 ++ 7 files changed, 78 insertions(+) diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApi.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApi.java index bfa2b10a..8f337e1e 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApi.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApi.java @@ -12,6 +12,7 @@ import org.springdoc.demo.app2.model.ModelApiResponse; import org.springdoc.demo.app2.model.Pet; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -139,4 +140,14 @@ default ResponseEntity uploadFile( return getDelegate().uploadFile(petId, additionalMetadata, file); } + @Operation(summary = "Get all Pets paged", description = "Get all Pets paged", security = { + @SecurityRequirement(name = "petstore_auth", scopes = { "write:pets", "read:pets" }) }, tags = { "pet" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Pet.class)))) + }) + @GetMapping(value = "/pet", produces = { "application/xml", "application/json" }) + default ResponseEntity> getAllPets(@NotNull Pageable pageable) { + return getDelegate().getAllPets(pageable); + } + } diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegate.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegate.java index c6e2df69..86f28568 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegate.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegate.java @@ -4,9 +4,11 @@ import java.util.Optional; import javax.validation.Valid; +import javax.validation.constraints.NotNull; import org.springdoc.demo.app2.model.ModelApiResponse; import org.springdoc.demo.app2.model.Pet; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -119,4 +121,8 @@ default ResponseEntity uploadFile( Long petId, } + default ResponseEntity> getAllPets(@NotNull Pageable pageable) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + } diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegateImpl.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegateImpl.java index bcad94af..23b500ec 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegateImpl.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/api/PetApiDelegateImpl.java @@ -9,6 +9,7 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; +import javax.validation.constraints.NotNull; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springdoc.demo.app2.model.Category; @@ -16,6 +17,7 @@ import org.springdoc.demo.app2.model.Pet; import org.springdoc.demo.app2.model.Tag; import org.springdoc.demo.app2.repository.PetRepository; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -148,4 +150,9 @@ private static Pet createPet(long id, Category category, String name, String[] u return pet; } + public ResponseEntity> getAllPets(@NotNull Pageable pageable) { + ApiUtil.checkApiKey(request); + return new ResponseEntity>(petRepository.findAll(pageable), HttpStatus.OK); + } + } diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java index 830f64e2..148c1abf 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java @@ -1,9 +1,15 @@ package org.springdoc.demo.app2.repository; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.util.Assert; +import java.beans.BeanInfo; +import java.beans.PropertyDescriptor; import java.util.*; @NoRepositoryBean @@ -13,6 +19,12 @@ public abstract class HashMapRepository implements CrudRepository abstract ID getEntityId(S entity); + private final BeanWrapper entityBeanInfo; + + public HashMapRepository(Class clazz) { + entityBeanInfo = new BeanWrapperImpl(clazz); + } + @Override public S save(S entity) { Assert.notNull(entity, "entity cannot be null"); @@ -34,6 +46,36 @@ public Collection findAll() { return entities.values(); } + public List findAll(Pageable pageable) { + final List result; + final Sort sort = pageable.getSort(); + if (sort == null) { + Comparator comp = new Comparator() { + @Override + public int compare(T t, T t1) { + int result = 0; + for (Sort.Order o : sort) { + final String prop = o.getProperty(); + PropertyDescriptor propDesc = entityBeanInfo.getPropertyDescriptor(prop); + result = ((Comparable) propDesc.createPropertyEditor(t).getValue()) + .compareTo((T) propDesc.createPropertyEditor(t1).getValue()); + if (o.isDescending()) { + result = -result; + } + if (result != 0) break; + } + return result; + } + }; + Set set = new TreeSet<>(comp); + set.addAll(entities.values()); + result = Collections.unmodifiableList(new ArrayList<>(set)); + } else { + result = Collections.unmodifiableList(new ArrayList<>(entities.values())); + } + return result; + } + @Override public long count() { return entities.keySet().size(); diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/OrderRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/OrderRepository.java index f798efbb..3e908e54 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/OrderRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/OrderRepository.java @@ -6,6 +6,10 @@ @Repository public class OrderRepository extends HashMapRepository { + public OrderRepository() { + super(Order.class); + } + @Override Long getEntityId(S order) { return order.getId(); diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/PetRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/PetRepository.java index dad00b41..0c90e3af 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/PetRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/PetRepository.java @@ -12,6 +12,10 @@ public class PetRepository extends HashMapRepository { private Long sequenceId = 1L; + public PetRepository() { + super(Pet.class); + } + @Override Long getEntityId(S pet) { return pet.getId(); diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/UserRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/UserRepository.java index dfb42947..6f6cc77e 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/UserRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/UserRepository.java @@ -6,6 +6,10 @@ @Repository public class UserRepository extends HashMapRepository { + public UserRepository() { + super(User.class); + } + @Override String getEntityId(S user) { return user.getUsername(); From 793a64f4c223ae7898018b32857a383094b4344c Mon Sep 17 00:00:00 2001 From: Thomas Pasch Date: Sat, 9 Nov 2019 20:43:02 +0100 Subject: [PATCH 2/3] fixes (cherry picked from commit bd1b23b8c074c0ae00c4fed24b6680cd6d217485) --- .../demo/app2/repository/HashMapRepository.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java index 148c1abf..7a14ff0c 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java @@ -49,16 +49,16 @@ public Collection findAll() { public List findAll(Pageable pageable) { final List result; final Sort sort = pageable.getSort(); - if (sort == null) { + if (sort != null) { Comparator comp = new Comparator() { @Override - public int compare(T t, T t1) { + public int compare(T t1, T t2) { int result = 0; for (Sort.Order o : sort) { final String prop = o.getProperty(); PropertyDescriptor propDesc = entityBeanInfo.getPropertyDescriptor(prop); - result = ((Comparable) propDesc.createPropertyEditor(t).getValue()) - .compareTo((T) propDesc.createPropertyEditor(t1).getValue()); + result = ((Comparable) propDesc.createPropertyEditor(t1).getValue()) + .compareTo((T) propDesc.createPropertyEditor(t2).getValue()); if (o.isDescending()) { result = -result; } @@ -67,7 +67,7 @@ public int compare(T t, T t1) { return result; } }; - Set set = new TreeSet<>(comp); + final Set set = new TreeSet<>(comp); set.addAll(entities.values()); result = Collections.unmodifiableList(new ArrayList<>(set)); } else { From fe5d919b98a0af00b2a940c5b46020fdb2dffa70 Mon Sep 17 00:00:00 2001 From: Thomas Pasch Date: Sun, 10 Nov 2019 11:11:20 +0100 Subject: [PATCH 3/3] fixes (cherry picked from commit 53ae25c89f1c4a321345b67f069a30ed856e7f48) --- .../app2/repository/HashMapRepository.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java index 7a14ff0c..e6b2209e 100644 --- a/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java +++ b/springdoc-openapi-test-app2/src/main/java/org/springdoc/demo/app2/repository/HashMapRepository.java @@ -21,7 +21,7 @@ public abstract class HashMapRepository implements CrudRepository private final BeanWrapper entityBeanInfo; - public HashMapRepository(Class clazz) { + protected HashMapRepository(Class clazz) { entityBeanInfo = new BeanWrapperImpl(clazz); } @@ -69,13 +69,35 @@ public int compare(T t1, T t2) { }; final Set set = new TreeSet<>(comp); set.addAll(entities.values()); - result = Collections.unmodifiableList(new ArrayList<>(set)); + result = getPageSlice(pageable, set); } else { - result = Collections.unmodifiableList(new ArrayList<>(entities.values())); + result = getPageSlice(pageable, entities.values()); } return result; } + private List getPageSlice(Pageable pageable, Collection col) { + final ArrayList all = new ArrayList<>(col); + final int size = all.size(); + final int psize = pageable.getPageSize(); + final int pnum = pageable.getPageNumber(); + if (pnum < 1) { + throw new IllegalArgumentException("page number must be 1 or more"); + } + if (psize < 1) { + throw new IllegalArgumentException("page size must be 1 or more"); + } + // inclusive + final int begin = (pnum - 1) * psize; + // exclusive + final int end = Math.min(begin + psize, size); + if (size < begin) { + return new ArrayList<>(); + } + // return of slice is valid because all is local to this method + return all.subList(begin, end); + } + @Override public long count() { return entities.keySet().size();