aboutsummaryrefslogtreecommitdiff
path: root/Week9 Webshop/src/com/camilstaps/shop/Shell.java
diff options
context:
space:
mode:
authorCamil Staps2015-04-18 13:44:44 +0200
committerCamil Staps2015-04-18 13:44:44 +0200
commit6a44b074f0169a1b0f9e92347af929c5e471746e (patch)
treeae5663fe7c69881bf4ecfedbef99c2505f8ec964 /Week9 Webshop/src/com/camilstaps/shop/Shell.java
parentAdded copyright to docs (diff)
Reorganised projects
Diffstat (limited to 'Week9 Webshop/src/com/camilstaps/shop/Shell.java')
-rw-r--r--Week9 Webshop/src/com/camilstaps/shop/Shell.java476
1 files changed, 476 insertions, 0 deletions
diff --git a/Week9 Webshop/src/com/camilstaps/shop/Shell.java b/Week9 Webshop/src/com/camilstaps/shop/Shell.java
new file mode 100644
index 0000000..7939963
--- /dev/null
+++ b/Week9 Webshop/src/com/camilstaps/shop/Shell.java
@@ -0,0 +1,476 @@
+/**
+ * Copyright (c) 2015 Camil Staps <info@camilstaps.nl>
+ * See the LICENSE file for copying permission.
+ */
+
+package com.camilstaps.shop;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Executing commands and providing output, using a UserInteraction and acting
+ * on a Database.
+ * @author Camil Staps, s4498062
+ */
+public class Shell {
+
+ /**
+ * The Database to work with
+ */
+ private final Database database;
+ /**
+ * The UserInteraction to use
+ */
+ private final UserInteraction ui;
+
+ /**
+ * The current User, if logged in
+ */
+ private User user;
+
+ public Shell(UserInteraction userInteraction) {
+ this.database = Database.getInstance();
+ this.ui = userInteraction;
+ }
+
+ /**
+ * Request commands, execute them, and show the results
+ */
+ public void run() {
+ while (true) {
+ Command command = ui.getCommand();
+ try {
+ Method method = getClass().getMethod("exec" + command.getCommand().substring(0,1).toUpperCase() + command.getCommand().substring(1));
+ method.invoke(this);
+
+ if (command.getCommand().equalsIgnoreCase("exit")) {
+ return;
+ }
+ } catch (NoSuchMethodException ex) {
+ ui.putStringln("Failure: no such command");
+ } catch (InvocationTargetException ex) {
+ ui.putStringln("Failure: " + ex.getCause().toString());
+ } catch (SecurityException | IllegalAccessException | IllegalArgumentException ex) {
+ ui.putStringln("Failure: unknown error");
+ }
+ }
+ }
+
+ /**
+ * Require that the visitor logs in
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException if the visitor fails to login
+ * @throws ItemNotFoundException if the visitor tries to login with a non-existing User number
+ */
+ public void requireLogin() throws LoginRequiredException, ItemNotFoundException {
+ if (user == null) {
+ ui.putStringln("You must login first.");
+
+ try {
+ execLogin();
+ } catch (InputRequiredException ex) {
+ }
+
+ if (user == null) {
+ throw new LoginRequiredException();
+ }
+ }
+ }
+
+ /**
+ * Require that an administrator is logged in
+ * @throws com.camilstaps.shop.Shell.AdminRequiredException if the visitor fails to login, or is not an administrator
+ * @throws ItemNotFoundException if the visitor tries to login with a non-existing User number
+ */
+ public void requireAdmin() throws AdminRequiredException, ItemNotFoundException {
+ if (user == null || !user.isAdmin()) {
+ ui.putStringln("You must login as an administrator first.");
+
+ try {
+ execLogin();
+ } catch (InputRequiredException ex) {
+ }
+
+ if (user == null || !user.isAdmin()) {
+ throw new AdminRequiredException();
+ }
+ }
+ }
+
+ /**
+ * Command: add an article
+ * @throws DuplicateEntryException
+ * @throws InputRequiredException
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execAddArticle() throws DuplicateEntryException, InputRequiredException, LoginRequiredException, ItemNotFoundException {
+ requireLogin();
+
+ String name = ui.getRequiredString("Name: ");
+ Category category = ui.getCategory();
+ float price = ui.getFloat("Price: ");
+
+ Article a = new Article(user, name, category, price);
+ database.addItem(a);
+ }
+
+ /**
+ * Command: set the article description
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execSetArticleDescription() throws LoginRequiredException, ItemNotFoundException, InputRequiredException {
+ requireLogin();
+
+ Article a;
+ if (user.isAdmin()) {
+ a = ui.getArticle();
+ } else {
+ a = ui.getArticle(user);
+ }
+
+ a.setDescription(ui.getRequiredString("Description: "));
+ }
+
+ /**
+ * Command: set the multimedia linked to an article
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execSetArticleMultimedia() throws LoginRequiredException, ItemNotFoundException, InputRequiredException {
+ requireLogin();
+
+ Article a;
+ if (user.isAdmin()) {
+ a = ui.getArticle();
+ } else {
+ a = ui.getArticle(user);
+ }
+
+ a.setMultimedia(new File(ui.getRequiredString("Multimedia: ")));
+ }
+
+ /**
+ * Command: remove an article
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execRemoveArticle() throws LoginRequiredException, ItemNotFoundException, InputRequiredException {
+ requireLogin();
+
+ Article a;
+ if (user.isAdmin()) {
+ a = ui.getArticle();
+ } else {
+ a = ui.getArticle(user);
+ }
+
+ database.removeItem(a);
+ }
+
+ /**
+ * Command: show a list of articles
+ */
+ public void execListArticles() {
+ for (Article a : database.getArticles()) {
+ ui.putStringln(a.toString());
+ }
+ }
+
+ /**
+ * Command: search for an article
+ */
+ public void execSearchArticle() {
+ String regex = ui.getString("Keywords: ");
+ for (Article a : database.searchArticle(Pattern.compile(regex))) {
+ ui.putStringln(a.toString());
+ }
+ }
+
+ /**
+ * Command: show detailed data about an article
+ * @throws InputRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execShowArticle() throws InputRequiredException, ItemNotFoundException {
+ Article a = ui.getArticle();
+ ui.putStringln(a.toString());
+ if (a.getDescription() != null) {
+ ui.putStringln(a.getDescription());
+ }
+ File multimedia = a.getMultimedia();
+ if (multimedia != null) {
+ ui.putStringln("Multimedia: " + multimedia.getPath());
+ }
+ if (user != null && user.isAdmin()) {
+ ui.putStringln("User: " + a.getOwner().toString(true));
+ }
+ }
+
+ /**
+ * Command: add a category
+ * @throws DuplicateEntryException
+ * @throws InputRequiredException
+ * @throws com.camilstaps.shop.Shell.AdminRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execAddCategory() throws DuplicateEntryException, InputRequiredException, AdminRequiredException, ItemNotFoundException {
+ requireAdmin();
+
+ String name = ui.getRequiredString("Name: ");
+ database.addItem(new Category(name));
+ }
+
+ /**
+ * Command: list categories
+ */
+ public void execListCategories() {
+ for (String c : database.getCategoryNames()) {
+ ui.putStringln(c);
+ }
+ }
+
+ /**
+ * Command: list users
+ * Administrators see a more detailed list
+ */
+ public void execListUsers() {
+ for (User u : database.getUsers()) {
+ ui.putStringln(u.toString(user != null && user.isAdmin()));
+ }
+ }
+
+ /**
+ * Command: register a new user
+ * @throws DuplicateEntryException
+ * @throws InputRequiredException
+ */
+ public void execRegister() throws DuplicateEntryException, InputRequiredException {
+ boolean addAsAdmin = false;
+
+ if (database.getUsers().isEmpty()) {
+ addAsAdmin = true;
+ ui.putStringln("This is the first user and will therefore be added as administrator.");
+ } else if (user != null && user.isAdmin()) {
+ addAsAdmin = ui.getBoolean("Add user as administrator");
+ }
+
+ String nr = ui.getRequiredString("Number: ");
+ String email = ui.getRequiredString("Email: ");
+
+ User u = new User(nr, email, addAsAdmin);
+
+ String password = u.setRandomPassword();
+ ui.putStringln("Password: " + password);
+
+ database.addItem(u);
+ }
+
+ /**
+ * Command: login
+ * @throws InputRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execLogin() throws InputRequiredException, ItemNotFoundException {
+ if (user != null) {
+ ui.putStringln("You are already logged in.");
+ return;
+ }
+
+ User u = ui.getUser();
+ String pw = ui.getRequiredString("Password: ");
+
+ if (!u.verify(pw)) {
+ ui.putStringln("Failed to login.");
+ return;
+ }
+
+ if (u.isBlocked()) {
+ ui.putStringln("You are blocked.");
+ return;
+ }
+
+ user = u;
+ }
+
+ /**
+ * Command: logout
+ */
+ public void execLogout() {
+ user = null;
+ }
+
+ /**
+ * Command: add an article to the cart
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execAddToCart() throws LoginRequiredException, ItemNotFoundException, InputRequiredException {
+ requireLogin();
+
+ user.getCart().add(ui.getArticle());
+ }
+
+ /**
+ * Command: remove an article from the cart
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execRemoveFromCart() throws LoginRequiredException, ItemNotFoundException {
+ requireLogin();
+
+ user.getCart().remove(ui.getArticle(user.getCart().getArticles()));
+ }
+
+ /**
+ * Command: list articles in the cart
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execListCart() throws LoginRequiredException, ItemNotFoundException {
+ requireLogin();
+
+ for (Article a : user.getCart().getArticles()) {
+ ui.putStringln(a.toString());
+ }
+
+ ui.putStringln("Total value: " + user.getCart().getTotalAmount());
+ }
+
+ /**
+ * Command: remove all articles from the cart
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ */
+ public void execClearCart() throws LoginRequiredException, ItemNotFoundException {
+ requireLogin();
+
+ if (ui.getBoolean("Are you sure?")) user.getCart().reset();
+ }
+
+ /**
+ * Command: checkout (create an Order using the current Cart)
+ * @throws ItemNotFoundException
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws DuplicateEntryException
+ */
+ public void execCheckout() throws ItemNotFoundException, LoginRequiredException, DuplicateEntryException {
+ requireLogin();
+
+ if (user.getCart().getArticles().isEmpty()) {
+ throw new ItemNotFoundException();
+ }
+
+ ui.putStringln("By checking out, you agree to pay the total amount.");
+ if (!ui.getBoolean("Do you agree?"))
+ return;
+
+ Order order = new Order(user);
+ database.addItem(order);
+
+ ui.putStringln("Your order has been added as " + order.toString());
+ }
+
+ /**
+ * Command: list orders
+ * @throws ItemNotFoundException
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ */
+ public void execListOrders() throws ItemNotFoundException, LoginRequiredException {
+ requireLogin();
+
+ Set<Order> orders;
+ if (user.isAdmin()) {
+ orders = database.getOrders();
+ } else {
+ orders = user.getOrders();
+ }
+ for (Order o : orders) {
+ ui.putStringln(o.toString());
+ }
+ }
+
+ /**
+ * Command: show detailed information about an order
+ * @throws com.camilstaps.shop.Shell.LoginRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execShowOrder() throws LoginRequiredException, ItemNotFoundException, InputRequiredException {
+ requireLogin();
+
+ Order o;
+ if (user.isAdmin()) {
+ o = ui.getOrder();
+ } else {
+ o = ui.getOrder(user);
+ }
+ ui.putStringln(o.toString());
+ for (Article a : o.getArticles()) {
+ ui.putStringln(" " + a.toString());
+ }
+ ui.putStringln("Total amount: " + o.getTotalAmount());
+ ui.putStringln("Paid: " + (o.isPaid() ? "yes" : "no"));
+ }
+
+ /**
+ * Command: set the paid status of an Order to true
+ * @throws com.camilstaps.shop.Shell.AdminRequiredException
+ * @throws ItemNotFoundException
+ * @throws InputRequiredException
+ */
+ public void execSetOrderPaid() throws AdminRequiredException, ItemNotFoundException, InputRequiredException {
+ requireAdmin();
+ ui.getOrder().setPaid(true);
+ }
+
+ /**
+ * Command: block a user
+ * @throws InputRequiredException
+ * @throws ItemNotFoundException
+ * @throws com.camilstaps.shop.Shell.AdminRequiredException
+ */
+ public void execBlockUser() throws InputRequiredException, ItemNotFoundException, AdminRequiredException {
+ requireAdmin();
+ ui.getUser().setBlocked(true);
+ }
+
+ /**
+ * Command: unblock a user
+ * @throws InputRequiredException
+ * @throws ItemNotFoundException
+ * @throws com.camilstaps.shop.Shell.AdminRequiredException
+ */
+ public void execUnblockUser() throws InputRequiredException, ItemNotFoundException, AdminRequiredException {
+ requireAdmin();
+ ui.getUser().setBlocked(false);
+ }
+
+ /**
+ * Command: save the database
+ */
+ public void execExit() {
+ database.write();
+ }
+
+ /**
+ * This Exception is thrown when the visitor is required to login, but fails
+ */
+ private class LoginRequiredException extends Exception {
+ }
+
+ /**
+ * This Exception is thrown when the visitor is required to login as an administrator, but fails
+ */
+ private class AdminRequiredException extends Exception {
+ }
+
+}