Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My project called Super Sushi demostrates the usage of OOP within Java.
by creating an ``Item Class`` with two interferes, menu and totalAmount
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 🍣 Super Sushi: A Spring Boot REST API Project 🚀

This project, **Super Sushi**, is a **Spring Boot** application written in **Java** that demonstrates the development of a **REST API**. Beyond the core application functionality, it serves as a practical example of **version control best practices**, showcasing a clear history of committed features, bug fixes, and subsequent refactoring.
This project, **Super Sushi**, is a **Spring Boot** application written in **Java** that demonstrates the development of a **REST API** and using **OOP**. Beyond the core application functionality, it serves as a practical example of **version control best practices**, showcasing a clear history of committed features, bug fixes, and subsequent refactoring.

-----

Expand All @@ -9,7 +9,7 @@ This project, **Super Sushi**, is a **Spring Boot** application written in **Jav
* **RESTful API Implementation:** Super Sushi establishes a functional REST API, with its specific endpoints and structure detailed within the project's subfolders.
* **Version Control Demonstration:** The project's commit history is an intentional artifact, illustrating the cyclical process of **committing features, encountering/fixing bugs, and re-fixing/refactoring** the codebase for improved stability and clarity.
* **Web Application Foundation:** The choice of a web application provides a tangible platform for interacting with the developed API.

* **OOP:** Using polymorphisms, interfaces, abstract and extending keywords.
-----

### 🎨 User Interface Development Disclaimer
Expand All @@ -24,21 +24,19 @@ The User Interface (UI) for this project was developed with assistance from an *

## UML

*(Insert your professional UML diagram image/link here.)*
![UML.png](UML.png)

-----

### 💻 Code Highlight: Dynamic Configuration

The following code snippet demonstrates a mechanism for **dynamically adjusting frontend variables** by editing the base HTML file. This technique ensures the application's client-side presentation remains correctly configured with the server-side state.

```java
// For example:
// File: src/main/java/com/SushiAPI/SushiAPI/controller/Receipt/ReceiptController.java
@GetMapping("/receipt")
public String showReceipt(Model model, @RequestBody String receiptData) {
public String showReceipt(Model model, @RequestBody String receiptData) {
JSONObject jsonObject = new JSONObject(receiptData);

StringBuilder htmlBuilder = new StringBuilder();
JSONArray jsonArray = jsonObject.getJSONArray("items");

Expand All @@ -61,4 +59,10 @@ The following code snippet demonstrates a mechanism for **dynamically adjusting
```

-----
## 🌐 FrontEnd Images: Home page
![img_3.png](img_3.png)

-----
## 🧭 API ROUTES
This image demostrates finding an item based on name
![img_2.png](img_2.png)
Binary file added UML.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions files/menus/Appetizers.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name|price|description|hot
Edamame|3.95|steamed Japanese soy bean W/ salt|false
Harumaki (4pcs)|3.95|Deep-fried japanese spring rolls|true
Gyoza (6pcs)|3.95|Pan fried Japanese dumpling|true
name|price|ingredients|hot|type
Edamame|3.95|steamed Japanese soy bean W/ salt|false|0
Harumaki (4pcs)|3.95|Deep-fried japanese spring rolls|true|0
Gyoza (6pcs)|3.95|Pan fried Japanese dumpling|true|0
Sunomono|10|Vinegary salad, octopus or shimp|false|1
13 changes: 7 additions & 6 deletions files/menus/Drinks.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name|price|qty|hot
Ramune Soda|2.95|5|false
Soda|2.95|5|false
Sparking Soda|2.95|5|false
Orange Juice|2.95|5|false
Apple Juice|2.95|5|false
name|price|size|hot|alcohol
Ramune Soda|3|5|false|false
Soda|2.95|12|false|false
Sparking Soda|3|5|false|false
Orange Juice|3|5|false|false
Apple Juice|3|5|false|false
Sake|3|5|false|true
11 changes: 11 additions & 0 deletions files/menus/Nigiri.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name|price|SpiceLevel|ingredients|raw|extra
Salmon Nigiri|4.50|1|Salmon, Sushi Rice, Wasabi|TRUE|Soy Sauce
Tuna Nigiri|4.75|1|Tuna, Sushi Rice, Wasabi|TRUE|Soy Sauce
Eel Nigiri|5.00|2|Grilled Eel, Sushi Rice, Sweet Soy Sauce|FALSE|Eel Sauce
Shrimp Nigiri|4.25|1|Boiled Shrimp, Sushi Rice, Wasabi|FALSE|Lemon Slice
Octopus Nigiri|4.00|1|Octopus, Sushi Rice, Wasabi|FALSE|Ponzu Sauce
Yellowtail Nigiri|4.75|2|Yellowtail, Sushi Rice, Wasabi|TRUE|Scallions
Scallop Nigiri|5.25|1|Scallop, Sushi Rice, Wasabi|TRUE|Yuzu Sauce
Tamago Nigiri|3.50|0|Sweet Egg Omelet, Sushi Rice, Nori|FALSE|Sesame Seeds
Ikura Nigiri|5.50|1|Salmon Roe, Sushi Rice, Nori|TRUE|Cucumber Slice
Uni Nigiri|6.00|1|Sea Urchin, Sushi Rice, Wasabi|TRUE|Shiso Leaf
9 changes: 5 additions & 4 deletions files/menus/Rolls.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name|price|available|ingredients|raw|extra
Crystal Roll|7|true|spicy scallop, crunchy, masago, tempura shrimp, asparagus, rolled in soy wrap, w/house special creamy sauce, eel sauce, bonito flake|true|null
Hulk Roll|7|true|salmon, yellowtail, jalapeno, topped w/yellowtail, avocado, wasabi tobiko, honey wasabi mayo|true|null
Fuji Roll|7|true|Spicy tuna, crunchy topped w/salmon, avocado, tobikko arare, spicy mayo|true|null
name|price|SpiceLevel|ingredients|raw|extra
Crystal Roll|7|0|spicy scallop, crunchy, masago, tempura shrimp, asparagus, rolled in soy wrap, w/house special creamy sauce, eel sauce, bonito flake|true|null
Hulk Roll|7|0|salmon, yellowtail, jalapeno, topped w/yellowtail, avocado, wasabi tobiko, honey wasabi mayo|true|null
Fuji Roll|7|0|Spicy tuna, crunchy topped w/salmon, avocado, tobikko arare, spicy mayo|true|null
dragon ball roll|20.0|5|null|true|null
Binary file added img_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
work on receipt
2 changes: 0 additions & 2 deletions src/main/java/com/SushiAPI/SushiAPI/SushiApiApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

@SpringBootApplication
public class SushiApiApplication {

public static void start() {
SpringApplication.run(SushiApiApplication.class);
}

}
Original file line number Diff line number Diff line change
@@ -1,82 +1,82 @@
package com.SushiAPI.SushiAPI.controller.API.Cart;

import com.SushiAPI.SushiAPI.models.Item;
import com.SushiAPI.SushiAPI.models.appetizers.appetizers;
import com.SushiAPI.SushiAPI.models.drinks.Drink;
import com.SushiAPI.SushiAPI.models.extra.Extra;
import com.SushiAPI.SushiAPI.models.nigiri.nigiri;
import com.SushiAPI.SushiAPI.models.rolls.Roll;
import com.SushiAPI.SushiAPI.utils.CartService;
import com.SushiAPI.SushiAPI.utils.MenuServices;
import com.SushiAPI.SushiAPI.utils.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import com.SushiAPI.SushiAPI.main;
import com.SushiAPI.SushiAPI.models.Appetizer.Seafoods;
import com.SushiAPI.SushiAPI.models.Appetizer.Traditional;
import com.SushiAPI.SushiAPI.models.Drinks.Alcohol;
import com.SushiAPI.SushiAPI.models.Drinks.Soda;
import com.SushiAPI.SushiAPI.models.MenuItem;
import com.SushiAPI.SushiAPI.models.Sushi.Nigiri;
import com.SushiAPI.SushiAPI.models.Sushi.Roll;
import com.SushiAPI.SushiAPI.utils.Services.CartService;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RestController
public class CartController {
@GetMapping("/api/cart")
public ResponseEntity<String> getMenu() {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(CartService.allItemsAsJson().toString());

}
public ResponseEntity<String> getMenu() { return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(CartService.AllItems().toString()); }

@PostMapping("/api/cart/add")
public boolean addItem(@RequestBody String addItem) {
public ResponseEntity<String> addItem(@RequestBody String addItem) {
JSONObject jsonObject = new JSONObject(addItem);
Item item = null;

JSONArray extras = jsonObject.getJSONArray("extras");

if(jsonObject.getString("category").equalsIgnoreCase("roll")) {
item = new Roll(jsonObject.getString("name"), jsonObject.getDouble("price"), false, jsonObject.getBoolean("isHot"), jsonObject.getBoolean("isAppetizer"), jsonObject.getBoolean("isRaw"), null, extras);
} else if(jsonObject.getString("category").equalsIgnoreCase("drink")) {
item = new Drink(jsonObject.getString("name"), jsonObject.getDouble("price"), jsonObject.getBoolean("isHot"), jsonObject.getString("description"));
} else if (jsonObject.getString("category").equalsIgnoreCase("nigiri")) {
item = new nigiri(jsonObject.getString("name"), jsonObject.getDouble("price"), false, jsonObject.getBoolean("isHot"), jsonObject.getBoolean("isAppetizer"), jsonObject.getBoolean("isRaw"), null, extras);
} else if (jsonObject.getString("category").equalsIgnoreCase("appetizer")) {
item = new appetizers(jsonObject.getString("name"), jsonObject.getDouble("price"), false, jsonObject.getBoolean("isHot"), true, jsonObject.getBoolean("isRaw"), null, extras);
MenuItem result = CartService.findItemByName(jsonObject.getString("name").strip());
if(result != null) {
if(!extras.isEmpty()) {
List<String> extrasList = IntStream.range(0, extras.length()).mapToObj(extras::getString).toList();
if(result.getCategory().equalsIgnoreCase("soda")) {
result = new Soda(result.getName(), result.getPrice(), result.getCold(), result.isAlcohol(), result.getIngredients(), extrasList);
} else if(result.getCategory().equalsIgnoreCase("Alcohol")) {
result = new Alcohol(result.getName(), result.getPrice(), result.getCold(), result.isAlcohol(), result.getIngredients(), extrasList);
} else if(result.getCategory().equalsIgnoreCase("Seafood Appetizer")) {
result = new Seafoods(result.getName(), result.getPrice(), result.getSpiceLevel(), result.getIngredients(), extrasList);
} else if(result.getCategory().equalsIgnoreCase("Traditional Appetizer")) {
result = new Traditional(result.getName(), result.getPrice(), result.getSpiceLevel(), result.getIngredients(), extrasList);
} else if(result.getCategory().equalsIgnoreCase("roll")) {
result = new Roll(result.getName(), result.getPrice(), result.getSpiceLevel(), result.getIngredients(), extrasList);
} else if(result.getCategory().equalsIgnoreCase("nigiri")) {
result = new Nigiri(result.getName(), result.getPrice(), result.getSpiceLevel(), result.getIngredients(), extrasList);
}
}
main.Cart.add(result);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result.toString());
}
CartService.addItem(item);
return true;
return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON).body("Can't find item");
}

@PostMapping("/api/cart/remove")
public boolean removeItem(@RequestBody String removeItem) {
public ResponseEntity<String> removeItem(@RequestBody String removeItem) {
JSONObject jsonObject = new JSONObject(removeItem);
Item item = null;
if(jsonObject.getString("category").equalsIgnoreCase("roll")) {
JSONArray myExtras = new JSONArray();
item = new Roll(jsonObject.getString("name"), jsonObject.getDouble("price"), false, jsonObject.getBoolean("isHot"), jsonObject.getBoolean("isAppetizer"), jsonObject.getBoolean("isRaw"), "Eel + avocado", myExtras);
} else if(jsonObject.getString("category").equalsIgnoreCase("drink")) {
item = new Drink(jsonObject.getString("name"), jsonObject.getDouble("price"), jsonObject.getBoolean("isHot"), jsonObject.getString("description"));
} else if (jsonObject.getString("category").equalsIgnoreCase("nigiri")) {
JSONArray myExtras = new JSONArray();
item = new nigiri(jsonObject.getString("name"), jsonObject.getDouble("price"), false, jsonObject.getBoolean("isHot"), jsonObject.getBoolean("isAppetizer"), jsonObject.getBoolean("isRaw"), "Eel + avocado", myExtras);
MenuItem result = CartService.findItemByName(jsonObject.getString("name").strip());
if(result != null) {
main.Cart.remove(result);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result.toString());
}
CartService.removeItem(item);
return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON).body("Can't find item");
}


@PostMapping("/api/cart/delete")
public boolean deleteAllItems() {
main.Cart.clear();
return true;
}


@GetMapping("/api/cart/search")
public ResponseEntity<List<Item>> searchCart(@RequestBody String searchItem) {
JSONObject jsonObject = new JSONObject(searchItem);
List<Item> items = CartService.searchItems(jsonObject.getString("query"));
return new ResponseEntity<List<Item>>(items, HttpStatus.OK);
public void searchCart(@RequestBody String searchItem) {
}

}
Original file line number Diff line number Diff line change
@@ -1,34 +1,84 @@
package com.SushiAPI.SushiAPI.controller.API.Menu;

import com.SushiAPI.SushiAPI.models.Item;
import com.SushiAPI.SushiAPI.utils.CartService;
import com.SushiAPI.SushiAPI.utils.MenuServices;
import com.SushiAPI.SushiAPI.main;
import com.SushiAPI.SushiAPI.models.Appetizer.Seafoods;
import com.SushiAPI.SushiAPI.models.Appetizer.Traditional;
import com.SushiAPI.SushiAPI.models.Drinks.Alcohol;
import com.SushiAPI.SushiAPI.models.Drinks.Soda;
import com.SushiAPI.SushiAPI.models.MenuItem;
import com.SushiAPI.SushiAPI.models.Sushi.Nigiri;
import com.SushiAPI.SushiAPI.models.Sushi.Roll;
import com.SushiAPI.SushiAPI.utils.Files;
import com.SushiAPI.SushiAPI.utils.Services.CartService;
import com.SushiAPI.SushiAPI.utils.Services.MenuService;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;


@RestController
public class MenuController {
@GetMapping("/api/menu")
public ResponseEntity<HashMap<String, ArrayList<Item>>> getMenu() {
HashMap<String, ArrayList<Item>> items = MenuServices.getMenuItems();
return new ResponseEntity<HashMap<String, ArrayList<Item>>>(items, HttpStatus.OK);
public ResponseEntity<HashMap<String, ArrayList<MenuItem>>> getMenu() {
HashMap<String, ArrayList<MenuItem>> items = MenuService.getMenuItems();
return new ResponseEntity<HashMap<String, ArrayList<MenuItem>>>(items, HttpStatus.OK);
}

@GetMapping("/api/menu/filter/") // api/menu/filter?search
public boolean searchItem(@RequestParam(required=true, defaultValue="") String searchQuery) {
// List<Item> items = MenuServices.getMenuItems(jsonObject.getString("query"));
return true;
public void searchItem(@RequestParam(required=true, defaultValue="") String searchQuery) {
return;
}

@PostMapping("/api/menu/addItem")
public ResponseEntity<String> addMenuItem(@RequestBody String addItem) {
JSONObject jsonObject = new JSONObject(addItem);
// grab body data
String itemType = jsonObject.getString("category");
String[] itemIngredients = jsonObject.getString("ingredients").split(",");
String itemName = jsonObject.getString("name");
double itemPrice = jsonObject.getDouble("price");
int itemSpicy = jsonObject.getInt("spiceLevel");

MenuItem item = null;
String csvChoice = "";
if(itemType.equalsIgnoreCase("traditional")) {
item = new Traditional(itemName, itemPrice, itemSpicy, null, null);
csvChoice = "Appetizers";
} else if(itemType.equalsIgnoreCase("seafood")) {
item = new Seafoods(itemName, itemPrice, itemSpicy, null, null);
csvChoice = "Appetizers";
} else if(itemType.equalsIgnoreCase("soda")) {
boolean itemAlcohol = jsonObject.getBoolean("isAlcohol");
boolean itemCold = jsonObject.getBoolean("isCold");
item = new Soda(itemName, itemPrice, itemCold, itemAlcohol, null, null);
csvChoice = "Drinks";

} else if(itemType.equalsIgnoreCase("alcohol")) {
boolean itemAlcohol = jsonObject.getBoolean("isAlcohol");
boolean itemCold = jsonObject.getBoolean("isCold");
item = new Alcohol(itemName, itemPrice, itemCold, itemAlcohol, null, null);
csvChoice = "Drinks";

} else if(itemType.equalsIgnoreCase("nigiri")) {
item = new Nigiri(itemName, itemPrice, itemSpicy, null, null);
csvChoice = "Nigiri";
} else if(itemType.equalsIgnoreCase("roll")) {
item = new Roll(itemName, itemPrice, itemSpicy, null, null);
csvChoice = "Rolls";
}
main.items.add(item); // add to menu
Files.writeFile("files/menus/" + csvChoice + ".csv", true, "\n" + item.toCsv());
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(item.toCsv() + "\n");
}

private static void extracted(String itemName, double itemPrice, int itemSpicy) {
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package com.SushiAPI.SushiAPI.controller.API.Order;

import com.SushiAPI.SushiAPI.models.Item;
import com.SushiAPI.SushiAPI.utils.CartService;
import com.SushiAPI.SushiAPI.utils.MenuServices;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import com.SushiAPI.SushiAPI.utils.Services.CartService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class OrderController {
@PostMapping("/api/order/pay")
public ResponseEntity<Boolean> payOrder() {
boolean paidOrder = CartService.pay();
return new ResponseEntity<Boolean>(paidOrder, HttpStatus.OK);
@PostMapping("/api/order/pay") // pay order
public boolean payOrder() {
return CartService.pay();
}

@GetMapping("/api/order/totalAmount")
public ResponseEntity<Double> totalAmountDue() {
return new ResponseEntity<Double>(CartService.totalAmount()
, HttpStatus.OK);
@GetMapping("/api/order/totalAmount") // ?tip=24 not required
public void totalAmountDue(@RequestParam(required = false, name = "tip") String tip) {

}
}
Loading