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