wm: java

ref: c38e733d9de9f416af3f1e629bc351c4723e2425
dir: /Bookproj/Lib.java/

View raw version
package Bookproj;

import java.io.Console;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Lib implements Library {
    static Admin adm;
    static User usr;
    static String logfile = "Log.txt";
    /* Username, Admin/User, ISBN, Book */
    protected HashMap<String, Admin> AdminList = new HashMap<String, Admin>();
    protected HashMap<String, User> UserList = new HashMap<String, User>();
    protected ArrayList<Admin> AdminQuery = new ArrayList<Admin>();
    int ResCount = 0;
    private HashMap<String, Book> BookList = new HashMap<String, Book>();
    private ArrayList<User> UserQuery = new ArrayList<User>();
    private ArrayList<Book> BookQuery = new ArrayList<Book>();

    public boolean Login(Admin u, String pass) {
        /* clear null */
        adm = null;
        if (u.Active)
            throw new IllegalStateException("Admin is already active");

        /* maybe later i want to do more stuff here */
        if (u.checkPass(pass)) {
            u.Active = true;
            Lib.adm = u;
            return true;
        } else
            return false;

    }

    public void Logout(Admin a) {
        if (!CheckAdmin(a.getUsername()))
            throw new NoSuchElementException("No such Admin exists.");

        if (!a.Active)
            throw new IllegalStateException("Admin is already inactive");

        a.Active = false;
    }

    public boolean Login(User u) {
        if (u.Active)
            throw new IllegalStateException("Admin is already active?");
        /* maybe later i want to do more stuff here */
        u.Active = true;
        usr = u;
        return true;
    }

    public void Logout(User u) {
        if (!CheckUser(u.getUsername()))
            throw new NoSuchElementException("No such User exists.");

        if (!u.Active)
            throw new IllegalStateException("User is already inactive.");

        u.Active = false;
    }

    public Admin NewAdmin(String user, String pass) {
        Admin a;
        if (CheckUser(user))
            throw new IllegalArgumentException("Admin already exists");

        /* if user is "admin", use defaults */
        if (user.equals("admin")) {
            pass = "pass";
            pass = Integer.toString(pass.hashCode());
        }
        a = new Admin(user, pass);

        this.AdminList.put(a.getUsername(), a);
        return a;
    }

    public DelErr DelAdmin(Admin u) {
        if (!u.getReserved().isEmpty())
            return DelErr.UserHasABook;

        this.AdminList.remove(u.getUsername(), u);
        return DelErr.Ok;
    }

    public User NewUser(String user, int age) {
        User u;
        if (CheckUser(user))
            throw new IllegalArgumentException("User already exists");

        u = new User(user, age);

        this.UserList.put(user, u);
        return u;
    }

    public DelErr DelUser(User u) {
        if (!u.getReserved().isEmpty())
            return DelErr.UserHasABook;
        this.UserList.remove(u.getUsername(), u);
        return DelErr.Ok;
    }

    public Book NewBook(String isbn, String name, String author, int agegroup, String abst) {
        Book b;
        if (CheckBook(isbn))
            throw new IllegalStateException("Book already exist");

        if (agegroup > 99)
            agegroup = 99;
        if (agegroup < 2)
            agegroup = 3;

        b = new Book(isbn, name, author, agegroup, abst);
        this.BookList.put(isbn, b);
        return b;
    }

    /* we shouldn't use MatchBook on UI, input is taken from user in string form */
    public DelErr DelBook(String isbn) {
        if (!CheckBook(isbn))
            return DelErr.NoBook;

        return DelBook(MatchBook(isbn));
    }

    public DelErr DelBook(Book b) {
        if (!b.getOwner().isEmpty())
            // System.err.println("User " + b.getOwner() + " have reserved this book.");
            // throw new IllegalStateException("Book is reserved.");
            return DelErr.UserHasABook;

        this.BookList.remove(b.getISBN());
        return DelErr.Ok;
    }
    public boolean CheckAdmin(String a)
    {
        for(Admin i : this.AdminList.values())
        {
            if(i.getUsername().equals(a))
            {
                return true;
            }
        }
        return false;
    }

    public Admin MatchAdmin(String un)
    {
        Admin a = null;

        for(Admin i : this.AdminList.values())
        {
            if(i.getUsername().equals(un))
                a = i;
        }

        if(a == null)
            throw new NoSuchElementException("No such Admin exists.");
        return a;
    }

    public boolean FindAdmin(AdminAttr k, Pattern p)
    {
        Matcher m;
        this.AdminQuery.clear();
        for(Admin i: this.AdminList.values())
        {
            m = p.matcher(i.toMap().get(k));
            if(m.find())
                AdminQuery.add(i);
        }
        if(this.AdminQuery.size() == 0)
            return false;
        else
            return true;
    }

    public boolean CheckUser(String u)
    {
        for(User i : this.UserList.values())
        {
            if(i.getUsername().equals(u))
            {
                return true;
            }
        }
        return false;
    }

    public User MatchUser(String un)
    {
        User u = null;

        for(User i : this.UserList.values())
        {
            if(i.getUsername().equals(un))
                u = i;
        }

        if(u == null)
        {
            throw new NoSuchElementException("No such User exists.");
        }
        return u;
    }
    public boolean CheckBook(String isbn) {
        boolean b = false;

        for (Book i : this.BookList.values()) {
            if (i.getISBN().equals(isbn))
                b = true;
        }

        return b;
    }

    public Book MatchBook(String isbn) {
        Book b = null;

        for (Book i : this.BookList.values()) {
            if (i.getISBN().equals(isbn))
                b = i;
        }

        if (b == null)
            throw new NoSuchElementException("No such book exists.");

        return b;
    }

    public boolean FindBook(BookAttr k, Pattern p) {
        Matcher m;
        this.BookQuery.clear();
        for (Book i : this.BookList.values()) {
            m = p.matcher(i.toMap().get(k));
            if (m.find())
                BookQuery.add(i);
        }
        if (this.BookQuery.size() == 0)
            return false;
        else
            return true;
    }

    public boolean FindUser(UserAttr k, Pattern p) {
        Matcher m;
        this.UserQuery.clear();
        for (User i : this.UserList.values()) {
            m = p.matcher(i.toMap().get(k));
            if (m.find())
                UserQuery.add(i);
        }
        if (this.UserQuery.size() == 0)
            return false;
        else
            return true;
    }

    public boolean FindBook(boolean q) {
        /* flush last query */
        this.BookQuery.clear();
        for (Book i : BookList.values()) {
            if (i.getStatus() == q)
                this.BookQuery.add(i);
        }
        if (this.BookQuery.size() == 0)
            return false;
        else
            return true;
    }

    /* user/admin's ID, ISBN */
    public TakeErr TakeBook(String un, String isbn) {
        Book b = this.BookList.get(isbn);
        if (this.CheckUser(un))
            return TakeBook(MatchUser(un), b);
        else if (this.CheckAdmin(un))
            return TakeBook(MatchAdmin(un), b);
        else
            return TakeErr.NoUser;
    }

    /* they shouldn't be able to get a book, but still */
    public TakeErr TakeBook(Admin a, Book b) {
        /* check if book is taken */
        if (b.getStatus())
            return TakeErr.BookReserved;

        /* he has some book? blasmphy! */
        if (!a.getReserved().isEmpty())
            return TakeErr.UserHasABook;

        /* check if ages match admin has no age anyway
        if(!b.AgeOk(a.getAge()))
            return Bookproj.TakeErr.Age; */

        a.setReserved(b.getISBN());

        b.setOwner(a.getUsername());
        b.setStatus(true);

        this.ResCount++;
        SaveLog(logfile, "[Take] " + b.getISBN() + " by " + a.getUsername() + '\n');
        return TakeErr.Ok;
    }

    public TakeErr TakeBook(User u, Book b) {
        /* check if book is taken */
        if (b.getStatus())
            return TakeErr.BookReserved;

        /* he has some book? blasmphy! */
        if (!u.getReserved().isEmpty())
            return TakeErr.UserHasABook;

        /* check if ages match */
        if (!b.AgeOk(u.getAge()))
            return TakeErr.Age;

        u.setReserved(b.getISBN());

        b.setOwner(u.getUsername());
        b.setStatus(true);

        this.ResCount++;
        SaveLog(logfile, "[Take] " + b.getISBN() + " by " + u.getUsername() + '\n');
        return TakeErr.Ok;
    }

    public TakeErr ReturnBook(Admin a) {
        Book b;
        if (a.getReserved().isEmpty())
            return TakeErr.NoBookReserved;

        if (!CheckBook(a.getReserved()))
            return TakeErr.NoBook;

        b = MatchBook(a.getReserved());

        a.clearReserved();

        b.setOwner(null);
        b.setStatus(false);

        this.ResCount--;
        SaveLog(logfile, "[Return] " + b.getISBN() + " by " + a.getUsername() + '\n');
        return TakeErr.Ok;
    }

    public TakeErr ReturnBook(User u) {
        Book b;
        if (u.getReserved().isEmpty())
            return TakeErr.NoBookReserved;

        if (!CheckBook(u.getReserved()))
            return TakeErr.NoBook;

        b = MatchBook(u.getReserved());

        u.clearReserved();

        b.setOwner(null);
        b.setStatus(false);

        this.ResCount--;
        SaveLog(logfile, "[Return] " + b.getISBN() + " by " + u.getUsername() + '\n');
        return TakeErr.Ok;
    }

    public void SaveLog(String fp, String in) {
        try {
            FileWriter fw = new FileWriter(fp, true);
            fw.append(in);
            fw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class conUI implements UI {
        public void Program() {
            while (true) {
                /* there is no admin! */
                if (AdminList.size() == 0)
                    AddAdmin();
                else
                    this.LoginMenu();
            }
        }

        public void LoginMenu() {
            String un, pass;

            System.out.print("Login> ");
            un = GetUsername();

            if (CheckAdmin(un)) {
                pass = this.GetPassword();

                Admin a = MatchAdmin(un);
                if (Login(a, pass)) {
                    System.out.println("Auth as " + a.getUsername() + " sucessful");
                    this.Menu(adm);
                } else {
                    System.out.println("Auth fail");
                    this.LoginMenu();
                }
            } else if (CheckUser(un)) {
                User u = MatchUser(un);
                if (Login(u)) {
                    System.out.println("Login sucessful");
                    this.Menu(usr);
                }
            } else {
                /* fool em! */
                this.GetPassword();
                System.out.println("Auth fail");
                this.LoginMenu();
            }
        }

        /* checks if password is valid, kinda like login */
        public boolean AskPass(Admin u) {
            String pass;
            System.out.println("Enter " + u.getUsername() + "'s password:");
            return u.checkPass(GetPassword());
        }

        public void Menu(Admin a) {
            int in;
            Scanner s = new Scanner(System.in);
            System.out.println("Welcome, " + a.getUsername() + "!");
            while (true) {
                System.out.print(
                        "\n" +
                                " 1) add admin\n" +
                                " 2) add user\n" +
                                " 3) add book\n\n" +

                                " 4) search admin\n" +
                                " 5) search user\n" +
                                " 6) search book\n\n" +

                                " 7) list admin\n" +
                                " 8) list user\n" +
                                " 9) list book\n\n" +

                                "10) delete admin\n" +
                                "11) delete user\n" +
                                "12) delete book\n\n" +

                                "13) take book\n" +
                                "14) return book\n\n" +

                                "15) logout\n");

                System.out.print("Admin Menu> ");
                while (!s.hasNextInt()) {
                    System.err.print("Please enter a valid input");
                    s.nextLine();
                    System.out.print("Admin Menu> ");
                }
                in = s.nextInt();
                s.nextLine();

                switch (in) {
                    case 1:
                        if (this.AskPass(adm))
                            this.AddAdmin();
                        else
                            System.err.println("Incorrect Password.");
                        break;
                    case 2:
                        if (this.AskPass(adm))
                            this.AddUser();
                        else
                            System.err.println("Incorrect Password.");
                        break;
                    case 3:
                        this.AddBook();
                        break;
                    case 4:
                        this.SearchAdmin();
                        break;
                    case 5:
                        this.SearchUser();
                        break;
                    case 6:
                        this.SearchBook();
                        break;
                    case 7:
                        this.ListAdmin();
                        break;
                    case 8:
                        this.ListUser();
                        break;
                    case 9:
                        this.ListBook();
                        break;

                    case 10:
                        System.out.println("This action requires admin password");
                        if (this.AskPass(adm)) /* current admin */
                            this.RemAdmin();
                        else
                            System.err.println("Incorrect Password.");
                        break;

                    case 11:
                        System.out.println("This action requires admin password");
                        if (this.AskPass(adm)) /* current admin */
                            this.RemUser();
                        else
                            System.err.println("Incorrect Password.");
                        break;
                    case 12:
                        this.RemBook();
                        break;

                    case 13:
                        this.TakeMenu(adm);
                        break;
                    case 14:
                        this.ReturnMenu(adm);
                        break;

                    case 15:
                        System.out.println("Logging out...");
                        Logout(adm);
                        return;
                    case 88:
                        NewBook("1", "java book", "jack c richard", 10, "a book about java and stuff");
                        NewBook("42", "C book", "dennis ritche", 18, "nightmares with pointers!");
                        NewBook("1453", "Fall of constantipole", "konstantinus", 5, "The city has fallen");
                        NewUser("ali", 20);
                        NewUser("jalal", 10);
                        break;
                    /* quit */
                    case 99:
                        System.out.print("Quit> Are you sure? (y/N)> ");
                        if (s.nextLine().equals("y"))
                            System.exit(0);
                        break;
                    default:
                        System.out.println("Invalid answer!, please try again.");
                        break;
                }
            }
        }

        public void Menu(User u) {
            int in;
            Scanner s = new Scanner(System.in);
            System.out.println("Hello, " + u.getUsername() + "!");
            while (true) {
                System.out.print(
                        "\n" +
                                " 1) search book\n" +
                                " 2) list book\n\n" +

                                " 3) take book\n" +
                                " 4) return book\n\n" +

                                " 5) logout\n");

                System.out.print("User Menu> ");
                while (!s.hasNextInt()) {
                    System.err.println("Please enter a valid input");
                    System.out.print("User Menu> ");
                    s.nextLine();
                }
                in = s.nextInt();
                s.nextLine();

                switch (in) {
                    case 1:
                        this.SearchBook();
                        break;
                    case 2:
                        this.ListBook();
                        break;
                    case 3:
                        this.TakeMenu(usr);
                        break;
                    case 4:
                        this.ReturnMenu(usr);
                        break;
                    case 5:
                        System.out.println("Logging out...");
                        Logout(usr);
                        return;
                    default:
                        System.out.println("Invalid answer!, please try again.");
                        break;
                }
            }
        }

        public String GetUsername() {
            Scanner s = new Scanner(System.in);
            String user;

            do {
                System.out.print("Username?> ");
                user = s.nextLine();
            } while (user.contains(" "));

            return user;
        }

        public String GetPassword() {
            String pass;

            if (System.console() != null) {
                Console c = System.console();
                do {
                    pass = new String(c.readPassword("Password?> "));
                } while (pass.equals(""));
            } else {
                /* no console? */
                Scanner s = new Scanner(System.in);
                do {
                    System.out.print("Password?> ");
                    pass = s.nextLine();
                } while (pass.equals(""));
            }

            /* encrypt it! */
            return Integer.toString(pass.hashCode());
        }

        public void SearchAdmin() {
            String attr, patt;
            Pattern pattern;
            AdminAttr ua;
            Scanner s = new Scanner(System.in);

            System.out.println("Attr: Username, Reserved, ID, RegTime, Age, Active");
            System.out.print("Find Admin> What?> ");
            attr = s.nextLine();

            if (attr.equalsIgnoreCase("Username"))
                ua = AdminAttr.Username;
            else if (attr.equalsIgnoreCase("Reserved"))
                ua = AdminAttr.Reserved;
            else if (attr.equalsIgnoreCase("ID"))
                ua = AdminAttr.ID;
            else if (attr.equalsIgnoreCase("RegTime"))
                ua = AdminAttr.RegTime;
            else if (attr.equalsIgnoreCase("Active"))
                ua = AdminAttr.Active;
            else {
                System.err.println("Invalid Attr");
                return;
            }

            System.out.print("Find Admin> Pattern?> ");
            patt = s.nextLine();
            pattern = Pattern.compile(patt, Pattern.CASE_INSENSITIVE);


            if (FindAdmin(ua, pattern)) {
                for (AdminAttr i : AdminAttr.values())
                    System.out.print(i + " | ");
                System.out.println();

                for (Admin i : AdminQuery) {
                    for (AdminAttr a : i.toMap().keySet())
                        System.out.print(i.toMap().get(a) + " | ");
                    System.out.println();
                }
            } else
                System.err.println("No match has found");
        }

        public void SearchUser() {
            String attr, patt;
            Pattern pattern;
            UserAttr ua;
            Scanner s = new Scanner(System.in);

            System.out.println("Attr: Username, Reserved, ID, RegTime, Age, Active");
            System.out.print("Find User> What?> ");
            attr = s.nextLine();

            if (attr.equalsIgnoreCase("Username"))
                ua = UserAttr.Username;
            else if (attr.equalsIgnoreCase("Reserved"))
                ua = UserAttr.Reserved;
            else if (attr.equalsIgnoreCase("ID"))
                ua = UserAttr.ID;
            else if (attr.equalsIgnoreCase("RegTime"))
                ua = UserAttr.RegTime;
            else if (attr.equalsIgnoreCase("Age"))
                ua = UserAttr.Age;
            else if (attr.equalsIgnoreCase("Active"))
                ua = UserAttr.Active;
            else {
                System.err.println("Invalid Attr");
                return;
            }

            System.out.print("Find User> Pattern> ");
            patt = s.nextLine();
            pattern = Pattern.compile(patt, Pattern.CASE_INSENSITIVE);


            if (FindUser(ua, pattern)) {
                for (UserAttr i : UserAttr.values())
                    System.out.print(i + " | ");
                System.out.println();

                for (User i : UserQuery) {
                    for (UserAttr a : i.toMap().keySet())
                        System.out.print(i.toMap().get(a) + " | ");
                    System.out.println();
                }
            } else
                System.err.println("No match has found");
        }

        public void SearchBook() {
            String attr, patt;
            Pattern pattern;
            BookAttr ba;
            Scanner s = new Scanner(System.in);

            System.out.println("Attr: Status, Name, Abstract, ISBN, AgeGroup etc.");
            System.out.print("Find Book> What?> ");
            attr = s.nextLine();

            if (attr.equalsIgnoreCase("ISBN"))
                ba = BookAttr.ISBN;
            else if (attr.equalsIgnoreCase("Status"))
                ba = BookAttr.Status;
            else if (attr.equalsIgnoreCase("Name"))
                ba = BookAttr.Name;
            else if (attr.equalsIgnoreCase("Author"))
                ba = BookAttr.Author;
            else if (attr.equalsIgnoreCase("Abstract"))
                ba = BookAttr.Abstract;
            else if (attr.equalsIgnoreCase("AgeGroup"))
                ba = BookAttr.AgeGroup;
            else {
                System.err.println("Invalid Attr");
                return;
            }

            System.out.print("Find Book> Pattern?> ");
            patt = s.nextLine();
            pattern = Pattern.compile(patt, Pattern.CASE_INSENSITIVE);

            if (FindBook(ba, pattern)) {
                for (BookAttr j : BookAttr.values())
                    System.out.print(j + " | ");
                System.out.println();

                for (Book j : BookQuery) {
                    for (BookAttr a : j.toMap().keySet())
                        System.out.print(j.toMap().get(a) + " | ");
                    System.out.println();
                }
            } else
                System.err.println("No match has found");
        }

        public void AddAdmin() {
            /* isn't java wonderful billy? */
            String user, pass;

            System.out.println("Setting up Admin:");

            /* ensure there is no admin with the same username */
            do {
                System.out.print("Add Admin> ");
                user = this.GetUsername();

                if (user.equals(""))
                    return;
            } while (CheckUser(user) || CheckAdmin(user));

            pass = this.GetPassword();

            NewAdmin(user, pass);
        }

        public void AddUser() {
            int age;
            String user;
            Scanner s = new Scanner(System.in);

            System.out.println("Setting up User:");

            /* ensure there is no admin with the same username */
            do {
                System.out.print("Add User> ");
                user = this.GetUsername();

                if (user.equals(""))
                    return;
            } while (CheckUser(user) || CheckAdmin(user));

            System.out.print("Add User> Age> ");
            while (!s.hasNextInt()) {
                System.err.println("Please enter a valid input");
                System.out.print("Add User> Age> ");
                s.nextLine();
            }
            age = s.nextInt();

            NewUser(user, age);
        }


        /* make checks better, reject empty input etc,
            regex perhaps? */
        public void AddBook() {
            int agegroup;
            String name, isbn, author, abs;
            Scanner s = new Scanner(System.in);

            System.out.print("Book> ISBN?> ");
            isbn = s.nextLine();
            if (isbn.equals(""))
                return;

            System.out.print("Book> Name?> ");
            name = s.nextLine();
            if (name.equals(""))
                return;


            System.out.print("Book> Author?> ");
            author = s.nextLine();
            if (author.equals(""))
                return;

            // XXX on a related note, should i care about dealing with multiline stuff?
            System.out.print("Book> Abstract?> ");
            abs = s.nextLine();
            if (abs.equals(""))
                return;

            do {
                System.out.print("Book> Age Group?> ");
                while (!s.hasNextInt()) {
                    System.err.println("Please enter a valid input");
                    System.out.print("Book> Age Group?> ");
                    s.nextLine();
                }
                agegroup = s.nextInt();
            } while ((agegroup > 99) || (agegroup < 2));
            /* ensure it's valid ^ */

            Book b = NewBook(isbn, name, author, agegroup, abs);
        }

        public void RemAdmin() {
            String un;
            Scanner s = new Scanner(System.in);

            System.out.print("Remove Admin> Username> ");
            un = s.nextLine();

            if (un.equals(""))
                return;

            if (!CheckAdmin(un)) {
                System.err.println("No such Admin has found.");
                return;
            }

            if (adm.getUsername().equals(un)) {
                System.err.println("You can't remove yourself.");
                return;
            }

            System.out.print("Remove Admin> Are you sure? (y/N)> ");
            if (!s.nextLine().equals("y"))
                return;

            Result(DelAdmin(MatchAdmin(un)));
        }

        public void RemUser() {
            String un;
            Scanner s = new Scanner(System.in);

            System.out.print("Remove User> Username> ");
            un = s.nextLine();

            if (un.equals(""))
                return;

            if (!CheckUser(un)) {
                System.err.println("No such user has found.");
                return;
            }

            System.out.print("Remove User> Are you sure? (y/N)> ");
            if (!s.nextLine().equals("y"))
                return;

            Result(DelUser(MatchUser(un)));
        }

        public void RemBook() {
            String isbn;
            Scanner s = new Scanner(System.in);

            System.out.print("Remove Book> isbn> ");
            isbn = s.nextLine();

            if (isbn.equals(""))
                return;

            if (!CheckBook(isbn)) {
                System.err.println("No such book has found.");
                return;
            }

            System.out.print("Remove Book> Are you sure? (y/N)> ");
            if (!s.nextLine().equals("y"))
                return;

            Result(DelBook(isbn));
        }

        public void ListAdmin() {
            for (AdminAttr i : AdminAttr.values())
                System.out.print(i + " | ");
            System.out.println();

            for (Admin i : AdminList.values()) {
                for (AdminAttr a : i.toMap().keySet())
                    System.out.print(i.toMap().get(a) + " | ");
                System.out.println();
            }
        }

        public void ListUser() {
            for (UserAttr i : UserAttr.values())
                System.out.print(i + " | ");
            System.out.println();

            for (User i : UserList.values()) {
                for (UserAttr a : i.toMap().keySet())
                    System.out.print(i.toMap().get(a) + " | ");
                System.out.println();
            }
        }

        public void ListBook() {
            for (BookAttr i : BookAttr.values())
                System.out.print(i + " | ");
            System.out.println();

            for (Book i : BookList.values()) {
                for (BookAttr a : i.toMap().keySet())
                    System.out.print(i.toMap().get(a) + " | ");
                System.out.println();
            }
        }

        public void TakeMenu(Admin a) {
            String isbn;
            Scanner s = new Scanner(System.in);

            if (!a.getReserved().isEmpty()) {
                System.err.println("Current Admin has already has a book (ISBN: " + a.getReserved() + ").");
                return;
            }

            System.out.println("Which book do you want to take? (you may find it's ISBN by Search menu)");

            do {
                System.out.print("Take> ISBN?> ");
                isbn = s.nextLine();

                if (isbn.equals(""))
                    return;

                if (!CheckBook(isbn))
                    System.err.println("No such book found, please try again");

            } while (isbn.contains(" ") || !CheckBook(isbn));

            Result(TakeBook(a, MatchBook(isbn)));
        }

        public void TakeMenu(User u) {
            String isbn;
            Scanner s = new Scanner(System.in);

            if (!u.getReserved().isEmpty()) {
                System.err.println("Current User has already has a book (ISBN: " + u.getReserved() + ").");
                return;
            }

            System.out.println("Which book do you want to take? (you may find it's ISBN by Search menu)");

            do {
                System.out.print("Take> ISBN?> ");
                isbn = s.nextLine();

                if (isbn.equals(""))
                    return;

                if (!CheckBook(isbn))
                    System.err.println("No such book found, please try again");

            } while (isbn.contains(" ") || !CheckBook(isbn));

            Result(TakeBook(u, MatchBook(isbn)));
        }

        public void ReturnMenu(Admin a) {
            Scanner s = new Scanner(System.in);

            if (a.getReserved().isEmpty()) {
                System.err.println("You have no books reserved.");
                return;
            }

            System.out.print("Return> Are you sure? (y/N)> ");

            if (s.nextLine().equals("y"))
                Result(ReturnBook(a));
            else
                System.out.println("Thought so.");
        }

        public void ReturnMenu(User u) {
            Scanner s = new Scanner(System.in);

            if (u.getReserved().isEmpty()) {
                System.err.println("You have no books reserved.");
                return;
            }

            System.out.print("Return> Are you sure (y/N)?> ");

            if (s.nextLine().equals("y"))
                Result(ReturnBook(u));
            else
                System.out.println("Thought so.");
        }

        public void Result(TakeErr res) {
            switch (res) {
                case NoBook:
                    System.err.println("No such book has found");
                    break;
                case BookReserved:
                    System.err.println("This book is reserved by someone else");
                    break;
                case NoBookReserved:
                    System.err.println("No book is reserved");
                    break;
                case NoUser:
                    System.err.println("No such User has found");
                    break;
                case UserHasABook:
                    System.err.println("User has already reserved a book");
                    break;
                case Age:
                    System.err.println("Age doesn't match!");
                    break;
                case Ok:
                    System.out.println("Done!");
                    break;
                default:
                    throw new IllegalStateException("Invalid Bookproj.TakeErr");
            }
        }

        public void Result(DelErr res) {
            switch (res) {
                case UserHasABook:
                    System.err.println("User has reserve a book, return it");
                    break;
                case BookReserved:
                    System.err.println("This book is reserved by someone else");
                    break;
                case NoBook:
                    System.err.println("No such book has found");
                    break;
                case NoUser:
                    System.err.println("No such user has found");
                    break;
                case Ok:
                    System.out.println("Done!");
                    break;
                default:
                    throw new IllegalStateException("Invalid Bookproj.DelErr");
            }
        }

    } /* end of conUI */
}