From def44ae3de05e843997aae45cc706e08efbe7dc1 Mon Sep 17 00:00:00 2001 From: Marcus Ikdal Date: Mon, 20 Jan 2025 13:24:17 +0100 Subject: [PATCH 1/2] completed core --- src/main/java/com/booleanuk/api/Main.java | 11 ++++ src/main/java/com/booleanuk/api/Product.java | 48 +++++++++++++++ .../com/booleanuk/api/ProductController.java | 48 +++++++++++++++ .../com/booleanuk/api/ProductRepository.java | 58 +++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 src/main/java/com/booleanuk/api/Main.java create mode 100644 src/main/java/com/booleanuk/api/Product.java create mode 100644 src/main/java/com/booleanuk/api/ProductController.java create mode 100644 src/main/java/com/booleanuk/api/ProductRepository.java diff --git a/src/main/java/com/booleanuk/api/Main.java b/src/main/java/com/booleanuk/api/Main.java new file mode 100644 index 0000000..8e749e0 --- /dev/null +++ b/src/main/java/com/booleanuk/api/Main.java @@ -0,0 +1,11 @@ +package com.booleanuk.api; + +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/Product.java b/src/main/java/com/booleanuk/api/Product.java new file mode 100644 index 0000000..c192667 --- /dev/null +++ b/src/main/java/com/booleanuk/api/Product.java @@ -0,0 +1,48 @@ +package com.booleanuk.api; + +public class Product { + private static int nextId = 1; + private final int id; + private String name; + private String category; + private int price; + + public Product(String name, String category, int price) { + this.id = nextId++; + this.name = name; + this.category = category; + this.price = price; + } + + public Product() { + this.id = nextId++; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public String getCategory() { + return category; + } + + public int getPrice() { + return price; + } + + public void setName(String name) { + this.name = name; + } + + public void setCategory(String category) { + this.category = category; + } + + public void setPrice(int price) { + this.price = price; + } +} diff --git a/src/main/java/com/booleanuk/api/ProductController.java b/src/main/java/com/booleanuk/api/ProductController.java new file mode 100644 index 0000000..7c51f02 --- /dev/null +++ b/src/main/java/com/booleanuk/api/ProductController.java @@ -0,0 +1,48 @@ +package com.booleanuk.api; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("products") +public class ProductController { + private ProductRepository repo = new ProductRepository(); + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public Product createProduct(@RequestBody Product product) { + return repo.create(product); + } + + @GetMapping + public List getAllProducts() { + return repo.getAll(); + } + + @GetMapping("/{id}") + public Product getSpecificProduct(@PathVariable int id) { + return repo.getProduct(id); + } + + @PutMapping("/{id}") + @ResponseStatus(HttpStatus.CREATED) + public Product updateProduct(@PathVariable int id, @RequestBody Product updated) { + return repo.update(id, updated); + } + + @DeleteMapping("/{id}") + public Product deleteProduct(@PathVariable int id) { + return repo.delete(id); + } + +} diff --git a/src/main/java/com/booleanuk/api/ProductRepository.java b/src/main/java/com/booleanuk/api/ProductRepository.java new file mode 100644 index 0000000..944199e --- /dev/null +++ b/src/main/java/com/booleanuk/api/ProductRepository.java @@ -0,0 +1,58 @@ +package com.booleanuk.api; + +import java.util.ArrayList; +import java.util.List; + +public class ProductRepository { + private List products = new ArrayList<>() { + { + add(new Product("How to build APIs", "Book", 1500)); + add(new Product("Grey bat", "Sports", 3000)); + } + }; + + List getAll() { + return products; + } + + Product getProduct(int id) { + for (Product p : products) { + if (p.getId() == id) { + return p; + } + } + return null; + } + + Product create(Product product) { + // check if product with same name exists + for (Product p : products) { + if (p.getName().equals(product.getName())) { + return null; + } + } + + products.add(product); + return product; + } + + Product update(int id, Product updated) { + Product product = getProduct(id); + if (product != null) { + product.setName(updated.getName()); + product.setCategory(updated.getCategory()); + product.setPrice(updated.getPrice()); + } + return product; + } + + Product delete(int id) { + for (Product p : products) { + if (p.getId() == id) { + products.remove(p); + return p; + } + } + return null; + } +} From b660174b6a7618fa2835bb09b50c59994429a91f Mon Sep 17 00:00:00 2001 From: Marcus Ikdal Date: Mon, 20 Jan 2025 14:37:17 +0100 Subject: [PATCH 2/2] completed extension --- src/main/java/com/booleanuk/api/Product.java | 4 -- .../com/booleanuk/api/ProductController.java | 41 ++++++++++++++++--- .../com/booleanuk/api/ProductRepository.java | 24 +++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/booleanuk/api/Product.java b/src/main/java/com/booleanuk/api/Product.java index c192667..5e876b3 100644 --- a/src/main/java/com/booleanuk/api/Product.java +++ b/src/main/java/com/booleanuk/api/Product.java @@ -14,10 +14,6 @@ public Product(String name, String category, int price) { this.price = price; } - public Product() { - this.id = nextId++; - } - public int getId() { return id; } diff --git a/src/main/java/com/booleanuk/api/ProductController.java b/src/main/java/com/booleanuk/api/ProductController.java index 7c51f02..6dcb892 100644 --- a/src/main/java/com/booleanuk/api/ProductController.java +++ b/src/main/java/com/booleanuk/api/ProductController.java @@ -1,5 +1,6 @@ package com.booleanuk.api; +import java.util.ArrayList; import java.util.List; import org.springframework.http.HttpStatus; @@ -10,8 +11,10 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; @RestController @RequestMapping("products") @@ -21,28 +24,54 @@ public class ProductController { @PostMapping @ResponseStatus(HttpStatus.CREATED) public Product createProduct(@RequestBody Product product) { - return repo.create(product); + Product created = repo.create(product); + if (created == null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Product with provided name already exists."); + } + return created; } @GetMapping - public List getAllProducts() { - return repo.getAll(); + public List getProducts(@RequestParam(required = false) String category) { + List result = new ArrayList<>(); + if (category != null) { + result = repo.getCategory(category); + if (result == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, + "No products of the provided category were found."); + } + } else { + result = repo.getAll(); + } + return result; } @GetMapping("/{id}") public Product getSpecificProduct(@PathVariable int id) { - return repo.getProduct(id); + Product product = repo.getProduct(id); + if (product == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found."); + } + return product; } @PutMapping("/{id}") @ResponseStatus(HttpStatus.CREATED) public Product updateProduct(@PathVariable int id, @RequestBody Product updated) { - return repo.update(id, updated); + Product product = repo.update(id, updated); + if (product == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found."); + } + return product; } @DeleteMapping("/{id}") public Product deleteProduct(@PathVariable int id) { - return repo.delete(id); + Product product = repo.delete(id); + if (product == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found."); + } + return product; } } diff --git a/src/main/java/com/booleanuk/api/ProductRepository.java b/src/main/java/com/booleanuk/api/ProductRepository.java index 944199e..fbf7eaa 100644 --- a/src/main/java/com/booleanuk/api/ProductRepository.java +++ b/src/main/java/com/booleanuk/api/ProductRepository.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + public class ProductRepository { private List products = new ArrayList<>() { { @@ -15,6 +18,20 @@ List getAll() { return products; } + List getCategory(String category) { + List filtered = new ArrayList<>(); + for (Product p : products) { + if (p.getCategory().toLowerCase().equals(category.toLowerCase())) { + filtered.add(p); + } + } + // return null if no items with this category + if (filtered.size() == 0) { + return null; + } + return filtered; + } + Product getProduct(int id) { for (Product p : products) { if (p.getId() == id) { @@ -39,6 +56,13 @@ Product create(Product product) { Product update(int id, Product updated) { Product product = getProduct(id); if (product != null) { + // check if product with updated name already exists + for (Product p : products) { + if (p.getName().equals(updated.getName())) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, + "Product with provided name already exists."); + } + } product.setName(updated.getName()); product.setCategory(updated.getCategory()); product.setPrice(updated.getPrice());