From d31edb0141b14cb081ae6a41aed4eebdc7f95d13 Mon Sep 17 00:00:00 2001 From: Hannah Holzheu <hh062@hdm-stuttgart.de> Date: Wed, 29 Nov 2023 17:02:19 +0100 Subject: [PATCH] updated Search Endpoint, not just plain text search available but also filtering of plants #23 --- requests.http | 16 +++-- .../hdm/mi/growbros/GrowBrosApplication.java | 3 + .../controllers/PlantsController.java | 9 ++- .../models/search/PlantSpecification.java | 59 +++++++++++++++++++ .../growbros/models/search/SearchRequest.java | 31 ++++++++++ .../repositories/PlantRepository.java | 24 +++++++- .../mi/growbros/service/PlantsService.java | 10 +++- 7 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 src/main/java/hdm/mi/growbros/models/search/PlantSpecification.java create mode 100644 src/main/java/hdm/mi/growbros/models/search/SearchRequest.java diff --git a/requests.http b/requests.http index d51fde8..da46d21 100644 --- a/requests.http +++ b/requests.http @@ -1,7 +1,6 @@ -### Get all plants +### abc GET http://localhost:8080/api/v1/plants -Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsdWthcy5rYXJzY2hAZ214LmRlIiwiaWF0IjoxNjk5ODczMDA4LCJleHAiOjE2OTk5NTk0MDh9.iU9gkWinFla3__ksuwLmKosevRXrrYlDdSQCPhNHxbM - +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsdWthcy5rYXJzY2hAZ214LmRlIiwiaWF0IjoxNzAxMTY0ODMxLCJleHAiOjE3MDEyNTEyMzF9.c8NrtsWI0TyZPDG6wgoibEZnqPtGuXjvd9u6HQ3lOEU ### Create account POST http://localhost:8080/api/v1/auth/register content-type: application/json @@ -19,5 +18,14 @@ content-type: application/json { "email": "lukas.karsch@gmx.de", - "password": "12345678" + "password": "myPassword123" } + +### SearchRequest +GET http://localhost:8080/api/v1/plants/search +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsdWthcy5rYXJzY2hAZ214LmRlIiwiaWF0IjoxNzAxMjczMDI4LCJleHAiOjE3MDEzNTk0Mjh9.eOZvYQZDfcv1rUG8sQ3E7nDuZjgQffWR_jQVMQK9WLw +content-type: application/json + +{ + "searchTerm": "Salat" +} \ No newline at end of file diff --git a/src/main/java/hdm/mi/growbros/GrowBrosApplication.java b/src/main/java/hdm/mi/growbros/GrowBrosApplication.java index 76f3ae0..a224f42 100644 --- a/src/main/java/hdm/mi/growbros/GrowBrosApplication.java +++ b/src/main/java/hdm/mi/growbros/GrowBrosApplication.java @@ -10,6 +10,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import java.lang.reflect.Array; +import java.util.ArrayList; + @SpringBootApplication public class GrowBrosApplication { diff --git a/src/main/java/hdm/mi/growbros/controllers/PlantsController.java b/src/main/java/hdm/mi/growbros/controllers/PlantsController.java index 6be9c24..abff9b6 100644 --- a/src/main/java/hdm/mi/growbros/controllers/PlantsController.java +++ b/src/main/java/hdm/mi/growbros/controllers/PlantsController.java @@ -1,6 +1,8 @@ package hdm.mi.growbros.controllers; import hdm.mi.growbros.models.plant.Plant; +import hdm.mi.growbros.models.plant.WaterDemand; +import hdm.mi.growbros.models.search.SearchRequest; import hdm.mi.growbros.service.PlantsService; import jakarta.validation.Valid; import org.springframework.web.bind.annotation.*; @@ -24,9 +26,10 @@ public class PlantsController { @GetMapping("api/v1/plants/randomPlants/{numberOfPlants}") public Collection<Plant> getRandomPlants(@PathVariable Integer numberOfPlants) {return plantsService.getRandomPlants(numberOfPlants);} - @GetMapping("api/v1/plants/search/{searchTerm}") - public Collection<Plant> getPlantsSearchedFor(@PathVariable String searchTerm){return plantsService.getPlantsSearchedFor(searchTerm);} - + @GetMapping("api/v1/plants/search") + public Collection<Plant> getPlantsSearchedFor(@RequestBody @Valid SearchRequest searchRequest){ + return plantsService.getPlantsSearchedFor(searchRequest); + } @PostMapping("/api/v1/plants") public void createPlant(@RequestBody @Valid Plant plant) { plantsService.createPlant(plant); diff --git a/src/main/java/hdm/mi/growbros/models/search/PlantSpecification.java b/src/main/java/hdm/mi/growbros/models/search/PlantSpecification.java new file mode 100644 index 0000000..3c70318 --- /dev/null +++ b/src/main/java/hdm/mi/growbros/models/search/PlantSpecification.java @@ -0,0 +1,59 @@ +package hdm.mi.growbros.models.search; + +import hdm.mi.growbros.models.plant.Plant; +import jakarta.persistence.criteria.Predicate; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + + + + +public class PlantSpecification { + + private static Logger log = LogManager.getLogger(PlantSpecification.class); + + public static Specification<Plant> withSearchCriteria(SearchRequest searchRequest) { + return (root, query, criteriaBuilder) -> { + Collection<Predicate> predicates = new ArrayList<>(); + + if (StringUtils.hasText(searchRequest.getSearchTerm())) { + predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("plantName")), + "%" + searchRequest.getSearchTerm().toLowerCase() + "%")); + } + if (searchRequest.getGroundType() != null) { + predicates.add(criteriaBuilder.equal(root.get("groundType"), searchRequest.getGroundType())); + } + if(searchRequest.getNutrientDemand()!=null){ + predicates.add(criteriaBuilder.equal(root.get("nutrientDemand"),searchRequest.getNutrientDemand())); + } + + if(searchRequest.getWaterDemand()!=null){ + predicates.add(criteriaBuilder.equal(root.get("waterDemand"),searchRequest.getWaterDemand())); + } + if(searchRequest.getLightingDemand()!=null){ + predicates.add(criteriaBuilder.equal(root.get("lightningDemand"),searchRequest.getLightingDemand())); + } + if(searchRequest.getHarvestWeekStart()!=null & searchRequest.getHarvestWeekEnd()!=null){ + predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("harvestWeekStart"),searchRequest.getHarvestWeekStart())); + predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("harvestWeekEnd"),searchRequest.getHarvestWeekEnd())); + } + if(searchRequest.getPlantWeekStart()!=null &searchRequest.getPlantWeekEnd()!=null){ + predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("plantWeekStart"),searchRequest.getPlantWeekStart())); + predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("plantWeekEnd"),searchRequest.getPlantWeekEnd())); + + } + if(searchRequest.getGrowthDuration()!=null){ + predicates.add(criteriaBuilder.equal(root.get("growthDuration"),searchRequest.getGrowthDuration())); + } + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }; + } +} diff --git a/src/main/java/hdm/mi/growbros/models/search/SearchRequest.java b/src/main/java/hdm/mi/growbros/models/search/SearchRequest.java new file mode 100644 index 0000000..356ccb3 --- /dev/null +++ b/src/main/java/hdm/mi/growbros/models/search/SearchRequest.java @@ -0,0 +1,31 @@ +package hdm.mi.growbros.models.search; + +import hdm.mi.growbros.models.plant.GroundType; +import hdm.mi.growbros.models.plant.LightingDemand; +import hdm.mi.growbros.models.plant.NutrientDemand; +import hdm.mi.growbros.models.plant.WaterDemand; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SearchRequest { + + private String searchTerm; + private WaterDemand waterDemand; + private NutrientDemand nutrientDemand; + private GroundType groundType; + private LightingDemand lightingDemand; + private Integer plantWeekStart; + private Integer plantWeekEnd; + private Integer harvestWeekStart; + private Integer harvestWeekEnd; + private Integer growthDuration; + +} diff --git a/src/main/java/hdm/mi/growbros/repositories/PlantRepository.java b/src/main/java/hdm/mi/growbros/repositories/PlantRepository.java index ec4ad8b..839b0a9 100644 --- a/src/main/java/hdm/mi/growbros/repositories/PlantRepository.java +++ b/src/main/java/hdm/mi/growbros/repositories/PlantRepository.java @@ -1,13 +1,33 @@ package hdm.mi.growbros.repositories; -import hdm.mi.growbros.models.plant.Plant; +import hdm.mi.growbros.models.plant.*; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; import java.util.Collection; +import java.util.List; @Repository -public interface PlantRepository extends JpaRepository<Plant, Long> { +public interface PlantRepository extends JpaRepository<Plant, Long>, JpaSpecificationExecutor<Plant> { Collection<Plant> findAllByNameContainingIgnoreCase(String searchTerm); + + Collection<Plant> findAllByWaterDemand(WaterDemand waterDemand); + + Collection<Plant> findAllByGroundType(GroundType groundType); + + Collection<Plant> findAllByLightingDemand(LightingDemand lightingDemand); + + Collection<Plant> findAllByNutrientDemand(NutrientDemand nutrientDemand); + + Collection<Plant> findAllByPlantWeekStartGreaterThanEqualAndPlantWeekEndIsLessThanEqual(Integer plantWeekStart, Integer plantWeekEnd); + + Collection<Plant> findAllByHarvestWeekStartGreaterThanEqualAndHarvestWeekEndLessThanEqual(Integer harvestWeekStart, Integer harvestWeekEnd); + + Collection<Plant> findAllByGrowthDurationIs(Integer growthDuration); + + + List<Plant> findAll(Specification<Plant> spec); } diff --git a/src/main/java/hdm/mi/growbros/service/PlantsService.java b/src/main/java/hdm/mi/growbros/service/PlantsService.java index e9fd4ff..618a139 100644 --- a/src/main/java/hdm/mi/growbros/service/PlantsService.java +++ b/src/main/java/hdm/mi/growbros/service/PlantsService.java @@ -1,10 +1,13 @@ package hdm.mi.growbros.service; import hdm.mi.growbros.models.plant.Plant; +import hdm.mi.growbros.models.search.PlantSpecification; import hdm.mi.growbros.repositories.PlantRepository; +import hdm.mi.growbros.models.search.SearchRequest; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -24,7 +27,7 @@ public class PlantsService { } public Collection<Plant> getRandomPlants(int numberOfPlants) { - List<Plant> allPlants = plantRepository.findAll(); // Annahme: findAll gibt alle Pflanzen zurück + List<Plant> allPlants = plantRepository.findAll(); if (allPlants.size() <= numberOfPlants) { return allPlants; @@ -43,8 +46,9 @@ public class PlantsService { } } - public Collection<Plant> getPlantsSearchedFor(String searchTerm){ - return plantRepository.findAllByNameContainingIgnoreCase(searchTerm); + public Collection<Plant> getPlantsSearchedFor(SearchRequest searchRequest) { + Specification<Plant> spec = PlantSpecification.withSearchCriteria(searchRequest); + return plantRepository.findAll(spec); } public void createPlant(Plant plant) { -- GitLab