From 762007e50125cd4cb20260590121deb5b1915d48 Mon Sep 17 00:00:00 2001 From: David Stern Date: Mon, 25 Aug 2025 14:06:53 +0200 Subject: [PATCH] Core and extensions --- src/main/java/com/booleanuk/Main.java | 12 +++ .../{ => controller}/BagelController.java | 5 +- .../api/bagels/{ => model/pojo}/Bagel.java | 2 +- .../repository}/BagelRepository.java | 4 +- .../controller/ProductController.java | 88 +++++++++++++++++++ .../products/controller/dto/ProductDto.java | 37 ++++++++ .../api/products/model/pojo/Product.java | 66 ++++++++++++++ .../model/repository/ProductRepository.java | 79 +++++++++++++++++ 8 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/booleanuk/Main.java rename src/main/java/com/booleanuk/api/bagels/{ => controller}/BagelController.java (62%) rename src/main/java/com/booleanuk/api/bagels/{ => model/pojo}/Bagel.java (89%) rename src/main/java/com/booleanuk/api/bagels/{ => model/repository}/BagelRepository.java (84%) create mode 100644 src/main/java/com/booleanuk/api/products/controller/ProductController.java create mode 100644 src/main/java/com/booleanuk/api/products/controller/dto/ProductDto.java create mode 100644 src/main/java/com/booleanuk/api/products/model/pojo/Product.java create mode 100644 src/main/java/com/booleanuk/api/products/model/repository/ProductRepository.java diff --git a/src/main/java/com/booleanuk/Main.java b/src/main/java/com/booleanuk/Main.java new file mode 100644 index 0000000..e4d509e --- /dev/null +++ b/src/main/java/com/booleanuk/Main.java @@ -0,0 +1,12 @@ +package com.booleanuk; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} diff --git a/src/main/java/com/booleanuk/api/bagels/BagelController.java b/src/main/java/com/booleanuk/api/bagels/controller/BagelController.java similarity index 62% rename from src/main/java/com/booleanuk/api/bagels/BagelController.java rename to src/main/java/com/booleanuk/api/bagels/controller/BagelController.java index cce2764..ec11f40 100644 --- a/src/main/java/com/booleanuk/api/bagels/BagelController.java +++ b/src/main/java/com/booleanuk/api/bagels/controller/BagelController.java @@ -1,4 +1,7 @@ -package com.booleanuk.api.bagels; +package com.booleanuk.api.bagels.controller; + +import com.booleanuk.api.bagels.model.pojo.Bagel; +import com.booleanuk.api.bagels.model.repository.BagelRepository; import java.util.List; diff --git a/src/main/java/com/booleanuk/api/bagels/Bagel.java b/src/main/java/com/booleanuk/api/bagels/model/pojo/Bagel.java similarity index 89% rename from src/main/java/com/booleanuk/api/bagels/Bagel.java rename to src/main/java/com/booleanuk/api/bagels/model/pojo/Bagel.java index 77a24a6..98dd946 100644 --- a/src/main/java/com/booleanuk/api/bagels/Bagel.java +++ b/src/main/java/com/booleanuk/api/bagels/model/pojo/Bagel.java @@ -1,4 +1,4 @@ -package com.booleanuk.api.bagels; +package com.booleanuk.api.bagels.model.pojo; public class Bagel { private int id; diff --git a/src/main/java/com/booleanuk/api/bagels/BagelRepository.java b/src/main/java/com/booleanuk/api/bagels/model/repository/BagelRepository.java similarity index 84% rename from src/main/java/com/booleanuk/api/bagels/BagelRepository.java rename to src/main/java/com/booleanuk/api/bagels/model/repository/BagelRepository.java index 320ddba..55ba335 100644 --- a/src/main/java/com/booleanuk/api/bagels/BagelRepository.java +++ b/src/main/java/com/booleanuk/api/bagels/model/repository/BagelRepository.java @@ -1,4 +1,6 @@ -package com.booleanuk.api.bagels; +package com.booleanuk.api.bagels.model.repository; + +import com.booleanuk.api.bagels.model.pojo.Bagel; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/booleanuk/api/products/controller/ProductController.java b/src/main/java/com/booleanuk/api/products/controller/ProductController.java new file mode 100644 index 0000000..7881692 --- /dev/null +++ b/src/main/java/com/booleanuk/api/products/controller/ProductController.java @@ -0,0 +1,88 @@ +package com.booleanuk.api.products.controller; + +import com.booleanuk.api.products.controller.dto.ProductDto; +import com.booleanuk.api.products.model.pojo.Product; +import com.booleanuk.api.products.model.repository.ProductRepository; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; + +@RestController +@RequestMapping("/products") +public class ProductController { + ProductRepository productRepository; + + public ProductController() { + this.productRepository = new ProductRepository(); + } + + // Get all + @GetMapping + public ResponseEntity> getAll() { + return ResponseEntity.ok(this.productRepository.findAll()); + } + + // Get by category + @GetMapping(params = "category") + public ResponseEntity getByCategory(@RequestParam String category) { + try { + return ResponseEntity.ok(this.productRepository.findAllByCategory(category)); + } catch (Exception e) { + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + } + + // Get by id + @GetMapping("/{id}") + public ResponseEntity getById(@PathVariable int id) { + try { + return ResponseEntity.ok(productRepository.findById(id)); + } catch (Exception e) { + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + } + + // Create + @PostMapping + public ResponseEntity createProduct(@RequestBody ProductDto productCreateDto) { + try { + return ResponseEntity.status(HttpStatus.CREATED).body(productRepository.create(new Product(productCreateDto))); + } catch (Exception e) { + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(e.getMessage()); + } + } + + // Update by id + @PutMapping("/{id}") + public ResponseEntity updateProductId(@PathVariable int id, @RequestBody ProductDto body) { + try { + return ResponseEntity.status(HttpStatus.CREATED).body(this.productRepository.updateById(id, body)); + } catch (Exception e) { + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + } + + // Delete by id + @DeleteMapping("/{id}") + public ResponseEntity deleteProduct(@PathVariable int id) { + try { + return ResponseEntity.ok(productRepository.deleteById(id)); + } catch (Exception e) { + return ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(e.getMessage()); + } + + } +} diff --git a/src/main/java/com/booleanuk/api/products/controller/dto/ProductDto.java b/src/main/java/com/booleanuk/api/products/controller/dto/ProductDto.java new file mode 100644 index 0000000..f80b1ac --- /dev/null +++ b/src/main/java/com/booleanuk/api/products/controller/dto/ProductDto.java @@ -0,0 +1,37 @@ +package com.booleanuk.api.products.controller.dto; + +public class ProductDto { + private String name; + private String category; + private int price; + + public ProductDto(String name, String category, int price) { + this.name = name; + this.category = category; + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } +} diff --git a/src/main/java/com/booleanuk/api/products/model/pojo/Product.java b/src/main/java/com/booleanuk/api/products/model/pojo/Product.java new file mode 100644 index 0000000..fae6802 --- /dev/null +++ b/src/main/java/com/booleanuk/api/products/model/pojo/Product.java @@ -0,0 +1,66 @@ +package com.booleanuk.api.products.model.pojo; + +import com.booleanuk.api.products.controller.dto.ProductDto; + +public class Product { + private static int nextId = 0; + private int id; + private String name; + private String category; + private int price; + + public Product() { + + } + + public Product(String name, String category, int price) { + setId(nextId++); + setName(name); + setCategory(category); + setPrice(price); + } + + public Product(ProductDto productCreateDto) { + this(productCreateDto.getName(), productCreateDto.getCategory(), productCreateDto.getPrice()); + } + + public static int getNextId() { + return nextId; + } + + public static void setNextId(int nextId) { + Product.nextId = nextId; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } +} diff --git a/src/main/java/com/booleanuk/api/products/model/repository/ProductRepository.java b/src/main/java/com/booleanuk/api/products/model/repository/ProductRepository.java new file mode 100644 index 0000000..e3783c4 --- /dev/null +++ b/src/main/java/com/booleanuk/api/products/model/repository/ProductRepository.java @@ -0,0 +1,79 @@ +package com.booleanuk.api.products.model.repository; + +import com.booleanuk.api.products.controller.dto.ProductDto; +import com.booleanuk.api.products.model.pojo.Product; + +import java.util.ArrayList; +import java.util.List; + +public class ProductRepository { + private List products = new ArrayList<>(); + + // Find all + public List findAll() { + return products; + } + + // Find all by category + public List findAllByCategory(String category) throws Exception { + List filtered = findAll().stream() + .filter(p -> category.equalsIgnoreCase(p.getCategory())) + .toList(); + + if (filtered.isEmpty()) { + throw new Exception("No products in the provided category were found"); + } + + return filtered; + } + + // Find by id + public Product findById(int id) throws Exception { + return products.stream() + .filter(p -> p.getId() == id) + .findFirst() + .orElseThrow(() -> new Exception("Not found")); + } + + // Create + public Product create(Product product) throws Exception { + List filtered = products + .stream() + .filter(p -> p.getName().equals(product.getName())) + .toList(); + + if (filtered.isEmpty()) { + Product newProduct = new Product(product.getName(), product.getCategory(), product.getPrice()); + products.add(newProduct); + return product; + } + + throw new Exception("Product with provided name already exists"); + } + + // Update by id + public Product updateById(int id, ProductDto body) throws Exception { + // Will throw if product with id not found + Product currentProduct = findById(id); + + // Check if name already in other product + List filtered = products.stream() + .filter(p -> p.getName().equals(body.getName())) + .toList(); + if (!filtered.isEmpty()) { + throw new Exception("Product with provided name already exists"); + } + currentProduct.setName(body.getName()); + currentProduct.setCategory(body.getCategory()); + currentProduct.setPrice(body.getPrice()); + return currentProduct; + } + + // Delete by id + public Product deleteById(int id) throws Exception { + Product productToDelete = findById(id); + products = products.stream().filter(p -> p.getId() != id).toList(); + return productToDelete; + } + +}