Skip to content
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
id 'org.springframework.boot' version '3.4.1'
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.example'
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/booleanuk/api/Main.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
43 changes: 43 additions & 0 deletions src/main/java/com/booleanuk/api/products/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.booleanuk.api.products;

public class Product {
private int id;
private String name;
private String category;
private int price;

public Product(int id, String name, String category, int price) {
this.id = id;
this.name = name;
this.category = category;
this.price = price;
}

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;
}
}
80 changes: 80 additions & 0 deletions src/main/java/com/booleanuk/api/products/ProductController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.booleanuk.api.products;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;
import java.util.NoSuchElementException;

@RestController
@RequestMapping("/products")
public class ProductController {
ProductRepository repository;

public ProductController(ProductRepository repository) {
this.repository = repository;
}

public ProductController() {
this.repository = new ProductRepository();
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Product create(@RequestBody Product product) {
Product p = repository.create(product);
if (p == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Product with provided name already exists.");
}
return p;
}

@GetMapping
@ResponseStatus(HttpStatus.OK)
public List<Product> getAll(@RequestParam(name="category", required=false) String category) {
List<Product> products;
if (category != null)
products = this.repository.findAll(category);
else
products = this.repository.findAll();
if (products.isEmpty())
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No products of the provided category were found.");
return products;
}

@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Product getOne(@PathVariable(name="id") int id) {
try {
return repository.find(id);
} catch (NoSuchElementException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found.");
}
}

@PutMapping("/{id}")
@ResponseStatus(HttpStatus.CREATED)
public Product update(@PathVariable(name="id") int id, @RequestBody Product product) {
Product updatedProduct;
try {
updatedProduct = repository.update(id, product);
} catch (NoSuchElementException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found.");
}
if (updatedProduct == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Product with provided name already exists.");
}
return updatedProduct;
}

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public Product delete(@PathVariable(name="id") int id) {
try {
return repository.delete(id);
} catch (NoSuchElementException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Product not found.");
}
}
}
74 changes: 74 additions & 0 deletions src/main/java/com/booleanuk/api/products/ProductRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.booleanuk.api.products;

import java.util.ArrayList;
import java.util.List;

public class ProductRepository {
private int idCounter = 1;
private List<Product> data;

public ProductRepository() {
data = new ArrayList<>();
create("Bagel", "Food", 12);
create("Apple", "Food", 7);
}

public Product create(String name, String category, int price) {
Product product = new Product(this.idCounter++, name, category, price);
this.data.add(product);
return product;
}

public Product create(Product product) {
if (!nameExists(product.getName())) {
return this.create(product.getName(), product.getCategory(), product.getPrice());
}
return null;
}

public List<Product> findAll(String category) {
return this.data.stream()
.filter(p -> p.getCategory().equals(category))
.toList();
}

public List<Product> findAll() {
return this.data;
}

public Product find(int id) {
return this.data.stream()
.filter(product -> product.getId() == id)
.findFirst()
.orElseThrow();
}

public Product update(int id, Product product) {
if (nameExists(product.getName(), id)) {
return null;
}
Product productToUpdate = find(id);
productToUpdate.setName(product.getName());
productToUpdate.setCategory(product.getCategory());
productToUpdate.setPrice(product.getPrice());
return productToUpdate;
}

public Product delete(int id) {
Product productToDelete = find(id);
data.remove(productToDelete);
return productToDelete;
}

private boolean nameExists(String name) {
return !this.data.stream()
.filter(p -> p.getName().equals(name))
.toList().isEmpty();
}

private boolean nameExists(String name, int excludeId) {
return !this.data.stream()
.filter(p -> p.getName().equals(name) && p.getId() != excludeId)
.toList().isEmpty();
}
}