wm: java

Download patch

ref: 3642ff2c921852babc8be83d5614fbadd32a8818
parent: 5f367957db24fa3924858e1c3427c70b4d3bc637
author: mkf <mkf@hp.lan>
date: Tue May 30 02:04:04 EDT 2023

add Bookproj, build.sh

--- /dev/null
+++ b/Bookproj/Admin.java
@@ -1,0 +1,46 @@
+package Bookproj;
+
+import java.time.LocalDateTime;
+import java.util.TreeMap;
+
+public class Admin extends BasicUser {
+    private String Password;
+
+    Admin(String user)
+    {
+        super(Role.Admin, user, (int)(Math.random()*100), LocalDateTime.now());
+
+    }
+    Admin(String user, String Pass)
+    {
+        /* maybe check if password is too easy? */
+        super(Role.Admin, user, (int)(Math.random()*100), LocalDateTime.now());
+        this.setPassword(Pass);
+    }
+
+    boolean checkPass(String pass) {
+        if (this.Password.equals(pass))
+            return true;
+        else
+            return false;
+    }
+
+    /* passwords should be unchangeable... for now */
+    protected void setPassword(String pass) {
+        this.Password = pass;
+    }
+
+    TreeMap<AdminAttr, String> toMap() {
+        TreeMap<AdminAttr, String> temp = new TreeMap<AdminAttr, String>();
+
+        temp.put(AdminAttr.Username, getUsername());
+        temp.put(AdminAttr.role, getRole().toString());
+        temp.put(AdminAttr.Reserved, getReserved());
+        temp.put(AdminAttr.ID, Integer.toString(getID()));
+        temp.put(AdminAttr.RegTime, getRegTime().toString());
+        /*  temp.put(Bookproj.AdminAttr.Password, this.Password); secrect secrect secrect */
+        temp.put(AdminAttr.Active, Boolean.toString(this.Active));
+
+        return temp;
+    }
+}
--- /dev/null
+++ b/Bookproj/AdminAttr.java
@@ -1,0 +1,11 @@
+package Bookproj;
+
+enum AdminAttr {
+    Username,
+    role,
+    Reserved,
+    ID,
+    RegTime,
+    // Password,
+    Active;
+}
--- /dev/null
+++ b/Bookproj/BasicUser.java
@@ -1,0 +1,52 @@
+package Bookproj;
+
+import java.time.LocalDateTime;
+
+public class BasicUser {
+    public boolean Active = false;
+    protected Role role;
+    protected String Username;
+    protected int ID;
+    protected LocalDateTime RegTime;
+    /* we will use isEmpty, even if it's not init-ed */
+    private String Reserved = new String();
+
+    public BasicUser(Role r, String u, int id, LocalDateTime rt) {
+        this.role = r;
+        this.Username = u;
+        this.ID = id;
+        this.RegTime = rt;
+    }
+
+    Role getRole() {
+        return this.role;
+    }
+
+    String getUsername() {
+        return this.Username;
+    }
+
+    int getID() {
+        return this.ID;
+    }
+
+    void clearReserved() {
+        this.Reserved = "";
+    }
+
+    void setReserved(String isbn) {
+        /* ensure he has no books */
+        if (!this.getReserved().isEmpty() && !isbn.equals(""))
+            throw new IllegalStateException("User already has a book!");
+
+        this.Reserved = isbn;
+    }
+
+    String getReserved() {
+        return this.Reserved;
+    }
+
+    LocalDateTime getRegTime() {
+        return this.RegTime;
+    }
+}
--- /dev/null
+++ b/Bookproj/Book.java
@@ -1,0 +1,88 @@
+package Bookproj;
+
+import java.util.TreeMap;
+
+public class Book {
+    protected String Abstract;
+    protected String Author;
+    protected String Name;
+    protected String ISBN;
+    protected int AgeGroup;
+    /* book is untaken by default */
+    private boolean Status = false;
+    private String Owner = ""; /* Username of user who reserved it */
+
+    Book(String isbn, String name, String author, int age, String abs)
+    {
+        /* joy of joys willy */
+        this.ISBN = isbn;
+        this.Name = name;
+        this.Author = author;
+        this.AgeGroup = age;
+        this.Abstract = abs;
+    }
+
+    boolean AgeOk(int age) {
+        if (this.AgeGroup <= age)
+            return true;
+        else
+            return false;
+    }
+
+    boolean setOwner(String u) {
+        if (!this.Owner.isEmpty())
+            return false;
+
+        this.Owner = u;
+        return true;
+    }
+
+    void setStatus(boolean b) {
+        if (this.Status == b)
+            throw new IllegalStateException("Status already set!");
+
+        this.Status = b;
+    }
+
+    boolean getStatus() {
+        return Status;
+    }
+
+    String getAbstract() {
+        return this.Abstract;
+    }
+
+    String getAuthor() {
+        return this.Author;
+    }
+
+    String getName() {
+        return this.Name;
+    }
+
+    String getISBN() {
+        return this.ISBN;
+    }
+
+    int getAgeGroup() {
+        return this.AgeGroup;
+    }
+
+    String getOwner() {
+        return this.Owner;
+    }
+
+    TreeMap<BookAttr, String> toMap() {
+        TreeMap<BookAttr, String> temp = new TreeMap<BookAttr, String>();
+
+        temp.put(BookAttr.ISBN, this.ISBN);
+        temp.put(BookAttr.Status, Boolean.toString(this.Status));
+        temp.put(BookAttr.Name, this.Name);
+        temp.put(BookAttr.Author, this.Author);
+
+        temp.put(BookAttr.AgeGroup, Integer.toString(this.AgeGroup));
+        temp.put(BookAttr.Abstract, this.Abstract);
+        temp.put(BookAttr.Owner, this.Owner);
+        return temp;
+    }
+}
--- /dev/null
+++ b/Bookproj/BookAttr.java
@@ -1,0 +1,11 @@
+package Bookproj;
+
+enum BookAttr {
+    ISBN,
+    Status,
+    Name,
+    Author,
+    AgeGroup,
+    Abstract,
+    Owner;
+}
--- /dev/null
+++ b/Bookproj/Books.java
@@ -1,0 +1,17 @@
+package Bookproj;
+
+import java.util.HashMap;
+import java.util.TreeMap;
+
+public class Books {
+    HashMap<BookAttr, String> Book = new HashMap<BookAttr, String>();
+    HashMap<String, HashMap> Booklist = new HashMap<String, HashMap>();
+
+    HashMap<String, TreeMap> Mkbl(HashMap<String, Book> bl) {
+        HashMap<String, TreeMap> list = new HashMap<String, TreeMap>();
+        for (Book i : bl.values()) {
+            list.put(i.getISBN(), i.toMap());
+        }
+        return list;
+    }
+}
--- /dev/null
+++ b/Bookproj/DelErr.java
@@ -1,0 +1,10 @@
+package Bookproj;
+
+/* used in DelAdmin, DelUser and DelBook */
+enum DelErr {
+    Ok,
+    BookReserved, /* book we are trying to delete has been reserved by someone */
+    UserHasABook, /* user we are trying to delete has a book */
+    NoBook,
+    NoUser;
+}
--- /dev/null
+++ b/Bookproj/Lib.java
@@ -1,0 +1,1110 @@
+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 */
+}
--- /dev/null
+++ b/Bookproj/Library.java
@@ -1,0 +1,117 @@
+package Bookproj;
+
+import java.util.regex.Pattern;
+
+public interface Library {
+    Admin NewAdmin(String user, String pass);
+
+    User NewUser(String user, int age);
+
+    Book NewBook(String isbn, String name, String author, int agegroup, String abst);
+
+    DelErr DelAdmin(Admin a);
+
+    DelErr DelUser(User u);
+
+    DelErr DelBook(Book b);
+
+    boolean Login(Admin a, String pass);
+
+    boolean Login(User u);
+
+    void Logout(Admin a);
+
+    void Logout(User u);
+
+    boolean CheckAdmin(String a);
+
+    boolean CheckUser(String u);
+
+    boolean CheckBook(String isbn);
+
+    Admin MatchAdmin(String un);
+
+    User MatchUser(String un);
+
+    Book MatchBook(String isbn);
+
+    boolean FindAdmin(AdminAttr k, Pattern p);
+
+    boolean FindUser(UserAttr k, Pattern p);
+
+    boolean FindBook(BookAttr k, Pattern p);
+
+    TakeErr TakeBook(String un, String isbn);
+
+    TakeErr TakeBook(Admin u, Book b);
+
+    TakeErr TakeBook(User u, Book b);
+
+    TakeErr ReturnBook(User u);
+
+    TakeErr ReturnBook(Admin u);
+
+    void SaveLog(String fp, String in);
+
+    interface UI {
+        void Program();
+
+        void LoginMenu();
+
+        /* checks password with user, gets input from GetPassword */
+        boolean AskPass(Admin u);
+        // boolean AskPass(User u);
+
+        /* different Menus, for different Users to handle */
+        void Menu(Admin u);
+
+        void Menu(User u);
+
+        /* Gets a String, either console or scanner, checks if it's valid or not, and encrypt it */
+        String GetUsername();
+
+        String GetPassword();
+
+        /* search foolan menu */
+        void SearchAdmin();
+
+        void SearchUser();
+
+        void SearchBook();
+
+        /* add foolan menu */
+        void AddAdmin();
+
+        void AddUser();
+
+        void AddBook();
+
+        /* remove foolan menu */
+        void RemAdmin();
+
+        void RemUser();
+
+        void RemBook(); // maybe it's stolen
+
+        /* list foolan menu */
+        void ListAdmin();
+
+        void ListUser();
+
+        void ListBook();
+
+        /* take and return book menus */
+        void TakeMenu(Admin a);
+
+        void TakeMenu(User u);
+
+        void ReturnMenu(Admin a);
+
+        void ReturnMenu(User u);
+
+        /* handles result of Take/IO/Del Funcations */
+        void Result(TakeErr res);
+
+        void Result(DelErr res);
+    }
+}
--- /dev/null
+++ b/Bookproj/Main.java
@@ -1,0 +1,9 @@
+package Bookproj;
+
+public class Main {
+    public static void main(String args[]) {
+        Lib l = new Lib();
+        Lib.UI ui = l.new conUI();
+        ui.Program();
+    }
+}
--- /dev/null
+++ b/Bookproj/Role.java
@@ -1,0 +1,6 @@
+package Bookproj;
+
+enum Role {
+    Admin,
+    User;
+}
--- /dev/null
+++ b/Bookproj/TakeErr.java
@@ -1,0 +1,13 @@
+package Bookproj;
+
+enum TakeErr {
+    Ok,
+
+    NoBook, /* no such book has found */
+    BookReserved, /* book is reserved by someone else */
+    NoBookReserved, /* no book is revserved */
+
+    NoUser, /* no such user has found */
+    UserHasABook, /* User has already registered a book */
+    Age; /* age doesn't match */
+}
--- /dev/null
+++ b/Bookproj/User.java
@@ -1,0 +1,39 @@
+package Bookproj;
+
+import java.time.LocalDateTime;
+import java.util.TreeMap;
+
+public class User extends BasicUser {
+    protected int Age;
+
+    User(String username, int age)
+    {
+        super(Role.User, username, (int)(Math.random()*1000+101), LocalDateTime.now());
+        this.Age = age;
+    }
+    int getAge() {
+        return this.Age;
+    }
+
+    boolean IsReserved(Book b) {
+        return (this.getReserved().equals(b.getISBN()));
+    }
+
+    boolean IsReserved(String ISBN) {
+        return (this.getReserved().equals(ISBN));
+    }
+
+    TreeMap<UserAttr, String> toMap() {
+        TreeMap<UserAttr, String> temp = new TreeMap<UserAttr, String>();
+
+        temp.put(UserAttr.Username, this.getUsername());
+        temp.put(UserAttr.role, getRole().toString());
+        temp.put(UserAttr.Reserved, getReserved());
+        temp.put(UserAttr.ID, Integer.toString(getID()));
+        temp.put(UserAttr.RegTime, getRegTime().toString());
+        temp.put(UserAttr.Age, Integer.toString(this.Age));
+        temp.put(UserAttr.Active, Boolean.toString(this.Active));
+
+        return temp;
+    }
+}
--- /dev/null
+++ b/Bookproj/UserAttr.java
@@ -1,0 +1,11 @@
+package Bookproj;
+
+enum UserAttr {
+    Username,
+    role,
+    Reserved,
+    ID,
+    RegTime,
+    Age,
+    Active;
+}
--- /dev/null
+++ b/Bookproj/build.sh
@@ -1,0 +1,2 @@
+javac -cp . *.java
+java -cp . Main