diff options
Diffstat (limited to 'Week9/src/com/camilstaps/shop/Shell.java')
-rw-r--r-- | Week9/src/com/camilstaps/shop/Shell.java | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/Week9/src/com/camilstaps/shop/Shell.java b/Week9/src/com/camilstaps/shop/Shell.java new file mode 100644 index 0000000..69d5207 --- /dev/null +++ b/Week9/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.getUser().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 { + } + +} |